/**
 @file sys_usw_queue_drop.c

 @date 2010-01-13

 @version v2.0

*/

/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/
#include "ctc_const.h"
#include "ctc_error.h"
#include "ctc_hash.h"
#include "ctc_warmboot.h"

#include "sys_usw_common.h"
#include "sys_usw_opf.h"
#include "sys_usw_ftm.h"
#include "sys_usw_qos.h"
#include "sys_usw_dmps.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_register.h"
#include "sys_usw_port_api.h"
#include "sys_usw_port.h"

#include "drv_api.h"

/****************************************************************************
 *
 * Global and Declaration
 *
 ****************************************************************************/

#define SYS_MAX_DROP_FACTOR 10
#define SYS_MIN_DROP_PRECEDENCE 0
#define SYS_MAX_DROP_PRECEDENCE 3
#define SYS_MAX_OOBFC_EGRESS_PORT_NUM  32
#define SYS_MAX_OOBFC_INGRESS_PORT_NUM 256
#define SYS_MAX_OOBFC_INGRESS_PRI_PORT_NUM 32
#define SYS_MAX_OOBFC_PORT_CFG_BASE 64

#define SYS_MAX_FCDL_TXQM_NUM     18
#define SYS_MAX_FCDL_TXQM_MAC_NUM 4

#define SYS_RESRC_IGS_COND(tc_min,total,sc,tc,port,port_tc) \
    ((tc_min<<5)|(total<<4)|(sc<<3)|(tc<<2)|(port <<1)|(port_tc<<0))

#define SYS_RESRC_EGS_COND(que_min,total,sc_pkt,sc,tc,port, grp,queue) \
    ((que_min<<7)|(total<<6)|(sc_pkt<<5)|(sc<<4)|(tc<<3)|(port<<2)|(grp<<1)|(queue<<0))



extern sys_queue_master_t* p_usw_queue_master[CTC_MAX_LOCAL_CHIP_NUM_PP];
/****************************************************************************
 *
 * Function
 *
 ****************************************************************************/
STATIC int32
_sys_usw_qos_fcdl_recover_get_fc_type(uint8 lchip, uint32 gport, uint8* pfc_en);
STATIC int32
_sys_usw_qos_fcdl_recover_drop_pkt(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable, uint8 pfc_en);
STATIC uint32
_sys_usw_qos_guarantee_hash_make_profile(sys_queue_guarantee_t* p_prof)
{
    return ctc_hash_caculate(sizeof(DsErmQueueGuaranteedThrdProfile_t), p_prof->p_ds);
}

/**
 @brief Queue drop hash comparison hook.
*/
STATIC bool
_sys_usw_qos_guarantee_hash_cmp_profile(sys_queue_guarantee_t* p_prof1,
                                           sys_queue_guarantee_t* p_prof2)
{
    uint32 cmd = 0;
    ds_t ds;
    void* p_ds = &ds;
    uint8 size = sizeof(DsErmQueueGuaranteedThrdProfile_t);
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = 0;
#endif

    if (!p_prof1 || !p_prof2 || !p_prof2->p_ds)
    {
        return FALSE;
    }

    if (0xFF == p_prof1->profile_id)/*for spool add error rollback*/
    {
        return TRUE;
    }
#ifdef CTC_SHELL_DEBUG_ON
    lchip = p_prof2->lchip;
#endif
    sal_memset(ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
    if (DRV_E_NONE != DRV_IOCTL(p_prof2->lchip, p_prof1->profile_id, cmd, &ds))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [ASIC] Hardware operation failed \n");
        return CTC_E_HW_FAIL;
    }
    if (!sal_memcmp(p_ds, p_prof2->p_ds, size))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_usw_qos_guarantee_alloc_profileId(sys_queue_guarantee_t* p_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_guarantee;
    opf.pool_index = 0;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, p_node->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        p_node->profile_id = value_32;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_guarantee_free_profileId(sys_queue_guarantee_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_guarantee;
    opf.pool_index = 0;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

int32
_sys_usw_qos_guarantee_profile_add_spool(uint8 lchip, sys_queue_guarantee_t* p_sys_profile_old,
                                                          sys_queue_guarantee_t* p_sys_profile_new,
                                                          sys_queue_guarantee_t** pp_sys_profile_get)
{
    ctc_spool_t* p_profile_pool    = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_profile_new);

    /*if use new date to replace old data, profile_id will not change*/
    if (p_sys_profile_old)
    {
        if (TRUE == _sys_usw_qos_guarantee_hash_cmp_profile(p_sys_profile_old, p_sys_profile_new))
        {
            *pp_sys_profile_get = p_sys_profile_old;

            return CTC_E_NONE;
        }
    }
    p_profile_pool = p_usw_queue_master[lchip]->p_queue_guarantee_pool;
    CTC_ERROR_RETURN(ctc_spool_add(p_profile_pool,p_sys_profile_new,p_sys_profile_old,pp_sys_profile_get));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile_id = %d\n",  (*pp_sys_profile_get)->profile_id);

    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_qos_fc_hash_make_profile(sys_qos_fc_profile_t* p_prof)
{
    uint8* data= (uint8*)(p_prof);
    uint8   length = sizeof(sys_qos_fc_profile_t) - sizeof(uint16);

    return ctc_hash_caculate(length, data);
}

/**
 @brief Queue drop hash comparison hook.
*/
STATIC bool
_sys_usw_qos_fc_hash_cmp_profile(sys_qos_fc_profile_t* p_prof1,
                                           sys_qos_fc_profile_t* p_prof2)
{
    if (!p_prof1 || !p_prof2)
    {
        return FALSE;
    }

    if (!sal_memcmp((uint8*)(p_prof1), (uint8*)(p_prof2), sizeof(sys_qos_fc_profile_t) - sizeof(uint16)))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_usw_qos_fc_alloc_profileId(sys_qos_fc_profile_t* p_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = *p_lchip;
#endif
    CTC_PTR_VALID_CHECK(p_node);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

    opf.pool_type  = p_node->type ? p_usw_queue_master[*p_lchip]->opf_type_resrc_fc_dropthrd : p_usw_queue_master[*p_lchip]->opf_type_resrc_fc;
    opf.pool_index = 0;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, p_node->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        p_node->profile_id = value_32;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_fc_free_profileId(sys_qos_fc_profile_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_node->type ? p_usw_queue_master[*p_lchip]->opf_type_resrc_fc_dropthrd : p_usw_queue_master[*p_lchip]->opf_type_resrc_fc;
    opf.pool_index = 0;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

int32
_sys_usw_qos_pfc_alloc_profileId(sys_qos_fc_profile_t* p_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;


    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_node->type ? p_usw_queue_master[*p_lchip]->opf_type_resrc_pfc_dropthrd : p_usw_queue_master[*p_lchip]->opf_type_resrc_pfc;
    opf.pool_index = 0;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, p_node->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        p_node->profile_id = value_32;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_pfc_free_profileId(sys_qos_fc_profile_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_node->type ? p_usw_queue_master[*p_lchip]->opf_type_resrc_pfc_dropthrd : p_usw_queue_master[*p_lchip]->opf_type_resrc_pfc;
    opf.pool_index = 0;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

int32
_sys_usw_qos_fc_profile_add_spool(uint8 lchip, uint8 is_pfc, uint8 is_dropthrd, sys_qos_fc_profile_t* p_sys_profile_old,
                                                          sys_qos_fc_profile_t* p_sys_profile_new,
                                                          sys_qos_fc_profile_t** pp_sys_profile_get)
{
    ctc_spool_t* p_profile_pool    = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_profile_new);

    /*if use new date to replace old data, profile_id will not change*/
    if (p_sys_profile_old)
    {
        if (TRUE == _sys_usw_qos_fc_hash_cmp_profile(p_sys_profile_old, p_sys_profile_new))
        {
            *pp_sys_profile_get = p_sys_profile_old;

            return CTC_E_NONE;
        }
    }

    if (is_pfc)
    {
        p_profile_pool = is_dropthrd? p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool : p_usw_queue_master[lchip]->p_pfc_profile_pool;
    }
    else
    {
        p_profile_pool = is_dropthrd? p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool : p_usw_queue_master[lchip]->p_fc_profile_pool;
    }

    CTC_ERROR_RETURN(ctc_spool_add(p_profile_pool,
                           p_sys_profile_new,
                           p_sys_profile_old,
                           pp_sys_profile_get));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile_id = %d\n",  (*pp_sys_profile_get)->profile_id);

    return CTC_E_NONE;
}

int32
_sys_usw_qos_oobfc_profile_add_spool(uint8 lchip, sys_qos_oobfc_profile_t* p_sys_profile_old,
                                                          sys_qos_oobfc_profile_t* p_sys_profile_new,
                                                          sys_qos_oobfc_profile_t** pp_sys_profile_get)
{
    ctc_spool_t* p_profile_pool    = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_profile_new);

    p_profile_pool = p_usw_queue_master[lchip]->p_oobfc_profile_pool;
    CTC_ERROR_RETURN(ctc_spool_add(p_profile_pool,
                           p_sys_profile_new,
                           p_sys_profile_old,
                           pp_sys_profile_get));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile_id = %d\n",  (*pp_sys_profile_get)->index.index);

    return CTC_E_NONE;
}

int32
sys_usw_qos_fc_add_static_profile(uint8 lchip)
{
    uint8 profile = 0;
    uint16 index = 0;
    uint32 cmd = 0;
    uint16 chan_id = 0;
    uint32 field_val = 0;
    uint8 tc = 0;
    sys_qos_fc_profile_t fc_data;
    sys_qos_fc_profile_t *p_fc_profile_get;
    sys_qos_oobfc_profile_t oobfc_data;
    sys_qos_oobfc_profile_t *p_oobfc_profile_get;
    DsIrmPortTcFlowControlThrdProfile_m ds_igr_port_tc_fc_profile;
    DsIrmPortFlowControlThrdProfile_m ds_igr_port_fc_profile;
    DsErmPortFcCfg_m egr_fc_profile;

    uint32 tc_thrd[2][3] =
    {
        {10576, 256, 224},
        {10576, 0x3FFFF, 0x3FFFF}
    };

    uint32 port_thrd[2][3] =
    {
        {10576, 256, 224},
        {10576, 0x3FFFF, 0x3FFFF}
    };

    sal_memset(&fc_data, 0, sizeof(fc_data));
    sal_memset(&oobfc_data, 0, sizeof(oobfc_data));
    sal_memset(&ds_igr_port_tc_fc_profile, 0, sizeof(DsIrmPortTcFlowControlThrdProfile_m));
    sal_memset(&ds_igr_port_fc_profile, 0, sizeof(DsIrmPortFlowControlThrdProfile_m));
    sal_memset(&egr_fc_profile, 0, sizeof(DsErmPortFcCfg_m));

    for (profile = 0; profile < 2; profile++)   /* here has 2 profile */
    {
        index = (profile << 2 | 0);

        SetDsIrmPortTcFlowControlThrdProfile(V, portTcXoffThrd_f  , &ds_igr_port_tc_fc_profile, tc_thrd[profile][1]);
        SetDsIrmPortTcFlowControlThrdProfile(V, portTcXonThrd_f  , &ds_igr_port_tc_fc_profile, tc_thrd[profile][2]);
        cmd = DRV_IOW(DsIrmPortTcFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_igr_port_tc_fc_profile));

        fc_data.thrd = 0;/*tc_thrd[profile][0]; pfc profile set as default,should release spool*/
        fc_data.xoff = tc_thrd[profile][1];
        fc_data.xon = tc_thrd[profile][2];
        fc_data.profile_id = profile;

        CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_pfc_profile_pool, &fc_data));

        p_fc_profile_get = ctc_spool_lookup(p_usw_queue_master[lchip]->p_pfc_profile_pool, &fc_data);

        if (profile == 0)
        {
            /* configure portTcThrdProfile ID, precascade
             * 0~63: normal fc/pfc
             * 64~95: oobfc fc/pfc
             */
            for (chan_id = 0; chan_id < 64 + SYS_QOS_OOBFC_INGRESS_MAX_STALL_NUM; chan_id++)
            {
                index = chan_id;
                field_val = 0;
                for (tc = 0; tc < 8; tc++)
                {
                    cmd = DRV_IOW(DsIrmPortStallCfg_t, DsIrmPortStallCfg_u_g1_0_portTcFlowControlThrdProfId_f + tc);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
                    p_usw_queue_master[lchip]->p_pfc_profile[chan_id][tc] = p_fc_profile_get;
                }
            }
        }
    }

    for (profile = 0; profile < 2; profile++)
    {
        index = profile << 2 | 0;
        SetDsIrmPortFlowControlThrdProfile(V, portXoffThrd_f  , &ds_igr_port_fc_profile, port_thrd[profile][1]);
        SetDsIrmPortFlowControlThrdProfile(V, portXonThrd_f  , &ds_igr_port_fc_profile, port_thrd[profile][2]);
        cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_igr_port_fc_profile));

        fc_data.thrd = 0;/*port_thrd[profile][0]; fc profile set as default,should release spool*/
        fc_data.xoff = port_thrd[profile][1];
        fc_data.xon = port_thrd[profile][2];
        fc_data.profile_id = profile;

        CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_fc_profile_pool, &fc_data));

        p_fc_profile_get = ctc_spool_lookup(p_usw_queue_master[lchip]->p_fc_profile_pool, &fc_data);

        if (profile == 0)
        {
            /* port threshold profile ID, 40*2*8=640 profId */
            field_val = 0;
            cmd = DRV_IOW(DsIrmPortStallCfg_t,  DsIrmPortStallCfg_portFlowControlThrdProfId_f);
            for (chan_id = 0; chan_id < 64 + SYS_QOS_OOBFC_INGRESS_MAX_STALL_NUM; chan_id ++)
            {
                index = chan_id;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
                p_usw_queue_master[lchip]->p_fc_profile[chan_id] = p_fc_profile_get;
            }
        }
    }

    /*egress oobfc*/
    for (profile = 0; profile < 2; profile++)
    {
        index = (profile << 3 | 0);
        SetDsErmPortFcCfg(V, xoffThrd_f  , &egr_fc_profile, tc_thrd[profile][1]);
        SetDsErmPortFcCfg(V, xonThrd_f  , &egr_fc_profile, tc_thrd[profile][2]);
        cmd = DRV_IOW(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        for(tc = 0; tc < 8; tc++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index + tc, cmd, &egr_fc_profile));

            oobfc_data.xoff[tc] = tc_thrd[profile][1];
            oobfc_data.xon[tc] = tc_thrd[profile][2];
        }
        oobfc_data.index.index = profile;
        CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_oobfc_profile_pool, &oobfc_data));

        p_oobfc_profile_get = ctc_spool_lookup(p_usw_queue_master[lchip]->p_oobfc_profile_pool, &oobfc_data);

        if (profile == 0)
        {
            /* configure portTcThrdProfile ID, precascade
             * 0~63: egerss oobfc/pfc
             */
            field_val = 0;
            cmd = DRV_IOW(DsErmPortCfg_t, DsErmPortCfg_portFcThrdProfId_f);
            for (chan_id = 0; chan_id < 64; chan_id++)
            {
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
                p_usw_queue_master[lchip]->p_oobfc_profile[chan_id] = p_oobfc_profile_get;
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_fcdl_detect_cpu_mac(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint8 enable                    = 0;
    uint8 prio_class                = 0;
    uint8 loop                      = 0;
    uint16 step                     = 0;
    uint16 index                    = 0;
    uint32 cmd                      = 0;
    
    Sgmac0RxPauseCfg_m sgmac_rx_pause_ctl;
    sal_memset(&sgmac_rx_pause_ctl, 0, sizeof(sgmac_rx_pause_ctl));

    step = (Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t) * (mac_id - SYS_CPU_MAC_ID_MIN);
    index = DRV_IS_TMG(lchip) ? (mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM)) : 0;
    cmd = DRV_IOR(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &sgmac_rx_pause_ctl));
    if (p_fcdl->enable)
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)/*config 2 cos together*/
        {
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn1_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f, &sgmac_rx_pause_ctl, p_fcdl->priority_class[0]);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos1_f, &sgmac_rx_pause_ctl, p_fcdl->priority_class[1]);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer1_f, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                enable = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
                if (!enable)
                {
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->enable);
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->priority_class[0]);
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->detect_mult);
                    break;
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_NO_RESOURCE;
            }
        }
    }
    else
    {
        if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
        {
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
            SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn1_f, &sgmac_rx_pause_ctl, p_fcdl->enable);
        }
        else
        {
            for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
            {
                enable = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
                prio_class = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl);

                if (enable && prio_class == p_fcdl->priority_class[0])
                {
                    SetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl, p_fcdl->enable);
                    break;
                }
            }

            if (loop == CTC_MAX_FCDL_DETECT_NUM)
            {
                return CTC_E_INVALID_PARAM;
            }
        }
    }

    cmd = DRV_IOW(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &sgmac_rx_pause_ctl));

    return CTC_E_NONE;
}

int32
_sys_usw_qos_get_fcdl_detect_cpu_mac(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint16 step                                  = 0;
    uint16 index                                 = 0;
    uint32 cmd                                   = 0;
    uint8 value[CTC_MAX_FCDL_DETECT_NUM]         = {0};
    uint8 detect_mult[CTC_MAX_FCDL_DETECT_NUM]   = {0};
    uint8 prio_class[CTC_MAX_FCDL_DETECT_NUM]    = {0};
    uint8 loop                                   = 0;

    Sgmac0RxPauseCfg_m sgmac_rx_pause_ctl;
    sal_memset(&sgmac_rx_pause_ctl, 0, sizeof(sgmac_rx_pause_ctl));

    step = (Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t) * (mac_id - SYS_CPU_MAC_ID_MIN);
    index = DRV_IS_TMG(lchip) ? (mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM)) : 0;
    cmd = DRV_IOR(Sgmac0RxPauseCfg_t + step, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &sgmac_rx_pause_ctl));
    for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
    {
        value[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectEn0_f + loop, &sgmac_rx_pause_ctl);
        detect_mult[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop, &sgmac_rx_pause_ctl);
        prio_class[loop] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f + loop, &sgmac_rx_pause_ctl);
        if (value[loop])
        {
            p_fcdl->valid_num++;
        }
    }

    if(value[0] && prio_class[0] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[0];
    }
    else if(value[1] && prio_class[1] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[1];
    }      
    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_fcdl_detect_network(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint8 enable                    = 0;
    uint8 prio_class                = 0;
    uint8 loop                      = 0;
    uint16 step                     = 0;
    uint16 step_1                   = 0;
    uint16 index                    = 0;
    uint32 tbl_id                   = 0;
    uint32 cmd                      = 0;
    
    if(DRV_FROM_TMM(lchip) && !DRV_IS_TMG(lchip))
    {
        McMacPauseRxCtl_m mac_rx_pause_ctl;
        sal_memset(&mac_rx_pause_ctl, 0, sizeof(McMacPauseRxCtl_m));

        step = (McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f - McMacPauseRxCtl_mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f)
                * (mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM));
        step_1 = McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn1_f - McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f;
        cmd = DRV_IOR(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM), cmd, &mac_rx_pause_ctl));
        if (p_fcdl->enable)
        {
            if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)/*config 2 cos together*/
            {
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[0]);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &mac_rx_pause_ctl, p_fcdl->priority_class[1]);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer1_f + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
            }
            else
            {
                for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + loop*step_1 + step, &mac_rx_pause_ctl);
                    if (!enable)
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + loop*step_1 + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + loop*step_1 + step, &mac_rx_pause_ctl, p_fcdl->priority_class[0]);
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + loop*step_1 + step, &mac_rx_pause_ctl, p_fcdl->detect_mult);
                        break;
                    }
                }

                if (loop == CTC_MAX_FCDL_DETECT_NUM)
                {
                    return CTC_E_NO_RESOURCE;
                }
            }
        }
        else
        {
            if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
            {
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn1_f + step, &mac_rx_pause_ctl, p_fcdl->enable);
            }
            else
            {
                for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
                {
                    enable = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + loop*step_1 + step, &mac_rx_pause_ctl);
                    prio_class = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + loop*step_1 + step, &mac_rx_pause_ctl);

                    if (enable && prio_class == p_fcdl->priority_class[0])
                    {
                        SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + loop*step_1 + step, &mac_rx_pause_ctl, p_fcdl->enable);
                        break;
                    }
                }

                if (loop == CTC_MAX_FCDL_DETECT_NUM)
                {
                    return CTC_E_INVALID_PARAM;
                }
            }
        }

        cmd = DRV_IOW(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM), cmd, &mac_rx_pause_ctl));
    }
    else
    {
        Sgmac0RxPauseCfg0_m rx_pause_cfg;
        sal_memset(&rx_pause_cfg, 0, sizeof(Sgmac0RxPauseCfg0_m));

        if (DRV_IS_TMG(lchip))
        {
            step = Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t;
            tbl_id = Sgmac0RxPauseCfg_t + step * (mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            index = mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM);
        }
        else
        {
            step = Sgmac1RxPauseCfg0_t - Sgmac0RxPauseCfg0_t;
            step_1 = Sgmac0RxPauseCfg0_cfgSgmac0RxPauseLockDetectEn1_f - Sgmac0RxPauseCfg0_cfgSgmac0RxPauseLockDetectEn1_f;
            tbl_id = Sgmac0RxPauseCfg0_t + (mac_id / 4) + ((mac_id % 4)*step);
            index = 0;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_cfg));
        if (p_fcdl->enable)
        {
            if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
            {
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f, &rx_pause_cfg, p_fcdl->enable);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn1_f, &rx_pause_cfg, p_fcdl->enable);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos0_f, &rx_pause_cfg, p_fcdl->priority_class[0]);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos1_f, &rx_pause_cfg, p_fcdl->priority_class[1]);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectTimer0_f, &rx_pause_cfg, p_fcdl->detect_mult);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectTimer1_f, &rx_pause_cfg, p_fcdl->detect_mult);
            }
            else
            {
                for(loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
                {
                    enable = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f + loop*step_1, &rx_pause_cfg);
                    if(!enable)
                    {
                        SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f + loop*step_1, &rx_pause_cfg, p_fcdl->enable);
                        SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos0_f + loop*step_1, &rx_pause_cfg, p_fcdl->priority_class[0]);
                        SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop*step_1, &rx_pause_cfg, p_fcdl->detect_mult);
                        break;
                    }
                }

                if(loop == CTC_MAX_FCDL_DETECT_NUM)
                {
                    return CTC_E_NO_RESOURCE;
                }
            }
        }
        else
        {
            if (CTC_MAX_FCDL_DETECT_NUM == p_fcdl->valid_num)
            {
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f, &rx_pause_cfg, p_fcdl->enable);
                SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn1_f, &rx_pause_cfg, p_fcdl->enable);
            }
            else
            {
                for(loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
                {
                    enable = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f + loop*step_1, &rx_pause_cfg);
                    prio_class = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos0_f + loop*step_1, &rx_pause_cfg);

                    if(enable && prio_class == p_fcdl->priority_class[0])
                    {
                        SetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f + loop*step_1, &rx_pause_cfg, p_fcdl->enable);
                        break;
                    }
                }

                if(loop == CTC_MAX_FCDL_DETECT_NUM)
                {
                    return CTC_E_INVALID_PARAM;
                }
            }
        }

        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_cfg));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_qos_get_fcdl_detect_network(uint8 lchip, uint32 mac_id, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint16 step                                  = 0;
    uint16 step_1                                = 0;
    uint16 index                                 = 0;
    uint32 tbl_id                                = 0;
    uint32 cmd                                   = 0;
    uint8 value[CTC_MAX_FCDL_DETECT_NUM]         = {0};
    uint8 detect_mult[CTC_MAX_FCDL_DETECT_NUM]   = {0};
    uint8 prio_class[CTC_MAX_FCDL_DETECT_NUM]    = {0};
    uint8 loop                                   = 0;

    if(DRV_FROM_TMM(lchip) && !DRV_IS_TMG(lchip))
    {
        McMacPauseRxCtl_m mac_rx_pause_ctl;
        sal_memset(&mac_rx_pause_ctl, 0, sizeof(McMacPauseRxCtl_m));

        step = (McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f - McMacPauseRxCtl_mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f)
                * (mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM));
        step_1 = McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn1_f - McMacPauseRxCtl_mcMacPauseRxCfg_1_cfgMcMacRxPauseLockDetectEn0_f;
        cmd = DRV_IOR(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM), cmd, &mac_rx_pause_ctl));
        for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
        {
            value[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectEn0_f + loop*step_1 + step, &mac_rx_pause_ctl);
            detect_mult[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectTimer0_f + loop*step_1 + step, &mac_rx_pause_ctl);
            prio_class[loop] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + loop*step_1 + step, &mac_rx_pause_ctl);
            if (value[loop])
            {
                p_fcdl->valid_num++;
            }
        }
    }
    else
    {
        Sgmac0RxPauseCfg0_m rx_pause_cfg;
        sal_memset(&rx_pause_cfg, 0, sizeof(Sgmac0RxPauseCfg0_m));

        if (DRV_IS_TMG(lchip))
        {
            step = Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t;
            tbl_id = Sgmac0RxPauseCfg_t + step * (mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            index = mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM);
        }
        else
        {
            step = Sgmac1RxPauseCfg0_t - Sgmac0RxPauseCfg0_t;
            step_1 = Sgmac0RxPauseCfg0_cfgSgmac0RxPauseLockDetectEn1_f - Sgmac0RxPauseCfg0_cfgSgmac0RxPauseLockDetectEn1_f;
            tbl_id = Sgmac0RxPauseCfg0_t + (mac_id / 4) + ((mac_id % 4)*step);
            index = 0;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_cfg));
        for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
        {
            value[loop] = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectEn0_f + loop*step_1, &rx_pause_cfg);
            detect_mult[loop] = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectTimer0_f + loop*step_1, &rx_pause_cfg);
            prio_class[loop] = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos0_f + loop*step_1, &rx_pause_cfg);
            if (value[loop])
            {
                p_fcdl->valid_num++;
            }
        }
    }

    if(value[0] && prio_class[0] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[0];
    }
    else if(value[1] && prio_class[1] == p_fcdl->priority_class[0])
    {
        p_fcdl->enable = 1;
        p_fcdl->detect_mult = detect_mult[1];
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_set_fcdl_detect(uint8 lchip, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint32 mac_id                   = 0;
    uint16 lport                    = 0;
    uint16 loop                     = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    CTC_VALUE_RANGE_CHECK(p_fcdl->valid_num, 1, CTC_MAX_FCDL_DETECT_NUM);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fcdl->gport, lchip, lport);
    for(loop = 0; loop < p_fcdl->valid_num; loop++)
    {
        CTC_MAX_VALUE_CHECK(p_fcdl->priority_class[loop], 7);
    }
    CTC_MAX_VALUE_CHECK(p_fcdl->mode, 2);
    if(p_fcdl->mode == 2 && p_fcdl->timeout == 0)
    {
        return CTC_E_INVALID_CONFIG;
    }

    if (DRV_FROM_AT(lchip))
    {
        if (MCHIP_QOS(lchip)->qos_fcdl_detect_mac)
        {
            CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_fcdl_detect_mac(lchip, p_fcdl, 0));
        }
    }
    else
    {
        dmps_port_info.gport = p_fcdl->gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_STATS_ID, (void *)&mac_id));
        if (SYS_DATAPATH_USELESS_MAC == mac_id)
        {
            return CTC_E_INVALID_CONFIG;
        }
        if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_set_fcdl_detect_cpu_mac(lchip, mac_id, p_fcdl));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_usw_qos_set_fcdl_detect_network(lchip, mac_id, p_fcdl));
        }
    }

    if(p_fcdl->enable)
    {
        /*first enable should start timer*/
        if((p_fcdl->mode == 2) && p_fcdl->timeout)
        {
            sys_usw_qos_fcdl_timer_en(lchip,TRUE);
        }
        p_usw_queue_master[lchip]->fcdl_info[lport].mode = p_fcdl->mode;
        p_usw_queue_master[lchip]->fcdl_info[lport].timeout = p_fcdl->mode == 2 ? p_fcdl->timeout : 0;
    }
    else
    {
        p_usw_queue_master[lchip]->fcdl_info[lport].mode = 0;
        p_usw_queue_master[lchip]->fcdl_info[lport].timeout = 0;
        /*all disable should end timer*/
        for(loop = 0; loop < SYS_USW_MAX_PORT_NUM_PER_CHIP; loop++)
        {
            if(p_usw_queue_master[lchip]->fcdl_info[loop].mode == 2)
            {
                break;
            }
        }
        if(p_usw_queue_master[lchip]->p_recover_timer && loop == SYS_USW_MAX_PORT_NUM_PER_CHIP)
        {
            sys_usw_qos_fcdl_timer_en(lchip, FALSE);
        }
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FCDL, 1);
    return CTC_E_NONE;
}

int32
sys_usw_qos_get_fcdl_detect(uint8 lchip, ctc_qos_resrc_fcdl_detect_t *p_fcdl)
{
    uint32 mac_id                   = 0;
    uint16 lport                    = 0;
    uint8 loop                      = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fcdl->gport, lchip, lport);
    for(loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
    {
        CTC_MAX_VALUE_CHECK(p_fcdl->priority_class[loop], 7);
    }

    if (DRV_FROM_AT(lchip))
    {
        if (MCHIP_QOS(lchip)->qos_fcdl_detect_mac)
        {
            CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_fcdl_detect_mac(lchip, p_fcdl, 1));
        }
    }
    else
    {
        dmps_port_info.gport = p_fcdl->gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_STATS_ID, (void *)&mac_id));
        if (SYS_DATAPATH_USELESS_MAC == mac_id)
        {
            return CTC_E_INVALID_CONFIG;
        }

        if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_get_fcdl_detect_cpu_mac(lchip, mac_id, p_fcdl));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_usw_qos_get_fcdl_detect_network(lchip, mac_id, p_fcdl));
        }
    }

    p_fcdl->mode = p_usw_queue_master[lchip]->fcdl_info[lport].mode;
    p_fcdl->timeout = p_usw_queue_master[lchip]->fcdl_info[lport].timeout;
    return CTC_E_NONE;
}

int32
sys_usw_qos_oobfc_get_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    uint32 chan_id = 0;
    uint32 cmd = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsErmPortFcCfg_m ds_egr_port_tc_fc_profile;

    if(!p_fc->is_pfc)
    {
        return CTC_E_INVALID_PARAM;
    }

    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_DMPS_INVALID_CHAN_ID)
    {
        return CTC_E_INVALID_PARAM;
    }

    if(DRV_FROM_TMM(lchip))
    {
        sal_memset(&ds_egr_port_tc_fc_profile, 0, sizeof(ds_egr_port_tc_fc_profile));
        cmd = DRV_IOR(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id << 4 | p_fc->priority_class, cmd, &ds_egr_port_tc_fc_profile));
        p_fc->xoff_thrd = GetDsErmPortFcCfg(V, xoffThrd_f, &ds_egr_port_tc_fc_profile);
        p_fc->xon_thrd = GetDsErmPortFcCfg(V, xonThrd_f, &ds_egr_port_tc_fc_profile);
        p_fc->drop_thrd = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD);
    }
    else
    {
        if(p_usw_queue_master[lchip]->p_oobfc_profile[chan_id])
        {
            p_fc->xoff_thrd = p_usw_queue_master[lchip]->p_oobfc_profile[chan_id]->xoff[p_fc->priority_class];
            p_fc->xon_thrd = p_usw_queue_master[lchip]->p_oobfc_profile[chan_id]->xon[p_fc->priority_class];
            p_fc->drop_thrd = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD);
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_oobfc_add_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    uint32 cmd = 0;
    uint32 old_profile_id = 0;
    uint32 profile_id = 0;
    uint32 chan_id = 0;
    uint8 loop = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_qos_oobfc_profile_t fc_data;
    sys_qos_oobfc_profile_t old_fc_data;
    sys_qos_oobfc_profile_t *p_sys_fc_profile_new = NULL;
    DsErmPortFcCfg_m ds_egr_port_tc_fc_profile;

    if(!p_fc->is_pfc)
    {
        return CTC_E_INVALID_PARAM;
    }

    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_COMMON_USELESS_CHANNEL)
    {
        return CTC_E_INVALID_PARAM;
    }

    if(DRV_FROM_TMM(lchip))
    {
        sal_memset(&ds_egr_port_tc_fc_profile, 0, sizeof(ds_egr_port_tc_fc_profile));
        SetDsErmPortFcCfg(V, xoffThrd_f  , &ds_egr_port_tc_fc_profile, p_fc->xoff_thrd);
        SetDsErmPortFcCfg(V, xonThrd_f  , &ds_egr_port_tc_fc_profile,  p_fc->xon_thrd);
        cmd = DRV_IOW(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id << 4 | p_fc->priority_class, cmd, &ds_egr_port_tc_fc_profile));
    }
    else
    {
    sal_memset(&fc_data, 0, sizeof(fc_data));
    sal_memset(&old_fc_data, 0, sizeof(old_fc_data));

    /*get old prof*/
    cmd = DRV_IOR(DsErmPortCfg_t, DsErmPortCfg_portFcThrdProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &old_profile_id));

    for(loop = 0; loop < 8; loop++)
    {
        sal_memset(&ds_egr_port_tc_fc_profile, 0, sizeof(ds_egr_port_tc_fc_profile));
        cmd = DRV_IOR(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, old_profile_id << 3 | loop, cmd, &ds_egr_port_tc_fc_profile));
        old_fc_data.xoff[loop] = GetDsErmPortFcCfg(V, xoffThrd_f, &ds_egr_port_tc_fc_profile);
        old_fc_data.xon[loop] = GetDsErmPortFcCfg(V, xonThrd_f, &ds_egr_port_tc_fc_profile);
    }
    old_fc_data.index.index = old_profile_id;

    /*get new prof*/
    sal_memcpy(&fc_data, &old_fc_data, sizeof(sys_qos_oobfc_profile_t));
    fc_data.xon[p_fc->priority_class] = p_fc->xon_thrd;
    fc_data.xoff[p_fc->priority_class] = p_fc->xoff_thrd;
    fc_data.index.index = 0;

    CTC_ERROR_RETURN(_sys_usw_qos_oobfc_profile_add_spool(lchip, &old_fc_data, &fc_data, &p_sys_fc_profile_new));

    profile_id = p_sys_fc_profile_new->index.index;
    for (loop = 0; loop < 8; loop++)
    {
        sal_memset(&ds_egr_port_tc_fc_profile, 0, sizeof(ds_egr_port_tc_fc_profile));
        SetDsErmPortFcCfg(V, xoffThrd_f  , &ds_egr_port_tc_fc_profile, fc_data.xoff[loop]);
        SetDsErmPortFcCfg(V, xonThrd_f  , &ds_egr_port_tc_fc_profile,  fc_data.xon[loop]);
        cmd = DRV_IOW(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, profile_id << 3 | loop, cmd, &ds_egr_port_tc_fc_profile));
    }
    cmd = DRV_IOW(DsErmPortCfg_t, DsErmPortCfg_portFcThrdProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &profile_id));

    p_usw_queue_master[lchip]->p_oobfc_profile[chan_id] = p_sys_fc_profile_new;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_OOBFC_PROFILE, 1);
    }
    return CTC_E_NONE;
}
int32
sys_usw_qos_fc_add_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    sys_qos_fc_profile_t fc_data;
    sys_qos_fc_profile_t fc_dropthrd_data;
    uint32 profile_id = 0;
    uint32 dropthrd_profile_id = 0;
    uint32 port_type = 0;
    uint32 cmd = 0;
    uint32 field_id = 0;
    uint16 chan_id = 0;
    uint32 value = 0;
    uint32 old_profile_id = 0;
    uint16 lport = 0;
    uint32 step = 0;
    uint8 loop = 0;
    uint32 cfg_idx = 0;
    sys_qos_fc_profile_t *p_sys_fc_profile = NULL;
    sys_qos_fc_profile_t *p_sys_fc_profile_new = NULL;
    sys_qos_fc_profile_t sys_fc_dropthrd_profile;
    sys_qos_fc_profile_t *p_sys_fc_dropthrd_profile = NULL;
    sys_qos_fc_profile_t *p_sys_fc_dropthrd_profile_new = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsIrmPortTcFlowControlThrdProfile_m ds_igr_port_tc_fc_profile;
    DsIrmPortFlowControlThrdProfile_m ds_igr_port_fc_profile;

    sal_memset(&fc_data, 0, sizeof(fc_data));
    sal_memset(&fc_dropthrd_data, 0, sizeof(fc_dropthrd_data));
    sal_memset(&sys_fc_dropthrd_profile, 0, sizeof(sys_fc_dropthrd_profile));

    if (DRV_IS_TMG(lchip) && p_fc->is_oobfc)
    {
        return CTC_E_NOT_SUPPORT;
    }
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fc->gport, lchip, lport);
    CTC_MAX_VALUE_CHECK(p_fc->priority_class, 7);
    CTC_VALUE_RANGE_CHECK(p_fc->xon_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
    CTC_VALUE_RANGE_CHECK(p_fc->xoff_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
    CTC_VALUE_RANGE_CHECK(p_fc->drop_thrd, 1, MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
    if(!(p_fc->xon_thrd < p_fc->xoff_thrd && p_fc->xoff_thrd < p_fc->drop_thrd))
    {
        return CTC_E_INVALID_PARAM;
    }


    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if (((SYS_DMPS_NETWORK_PORT == port_type) || (SYS_DMPS_CPUMAC_NETWORK_PORT == port_type)) && p_fc->is_oobfc)/*egress oobfc*/
    {
        return sys_usw_qos_oobfc_add_profile(lchip, p_fc);
    }

    CTC_ERROR_RETURN(_sys_usw_get_channel_by_port(lchip, p_fc->gport, &chan_id));
    if (chan_id == SYS_DMPS_INVALID_CHAN_ID)
    {
        return CTC_E_INVALID_PARAM;
    }

    fc_data.xon = p_fc->xon_thrd;
    fc_data.xoff = p_fc->xoff_thrd;
    fc_dropthrd_data.thrd = p_fc->drop_thrd / 8 * 8;
    fc_dropthrd_data.type = 1;

    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cfg_idx = p_fc->is_oobfc ? lport : chan_id;
    }
    else if(p_fc->is_oobfc)/*tm ingress oobfc, for localPhyPort, cfg_idx:64-95*/
    {
        if (p_fc->is_pfc)
        {
            cfg_idx = lport - CTC_MAP_GPORT_TO_LPORT(p_usw_queue_master[lchip]->oobfc_group_info.port_base) + SYS_MAX_OOBFC_PORT_CFG_BASE;/*[64,96)*/
            CTC_VALUE_RANGE_CHECK(cfg_idx, 64, 95);
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][p_fc->priority_class];
            cmd = DRV_IOR(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g1_portTcLimitedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (cfg_idx << 3) + p_fc->priority_class, cmd, &old_profile_id));
            if (p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class])
            {
                p_sys_fc_dropthrd_profile =  p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class];
            }
        }
        else
        {
            cfg_idx = lport / 8 + SYS_MAX_OOBFC_PORT_CFG_BASE;
            CTC_VALUE_RANGE_CHECK(cfg_idx, 64, 95);
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][lport%8];
            cmd = DRV_IOR(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g2_portLimitedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &old_profile_id));
            if (p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport%8])
            {
                p_sys_fc_dropthrd_profile = p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport%8];
            }
        }
    }
    else /*tm normal flowctl, for network chan, cfg_idx:0-63*/
    {
        cfg_idx = chan_id;/*[0,64)*/

        if (p_fc->is_pfc)
        {
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][p_fc->priority_class];
            cmd = DRV_IOR(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g1_portTcLimitedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (cfg_idx << 3) + p_fc->priority_class, cmd, &old_profile_id));
            if (p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class])
            {
                p_sys_fc_dropthrd_profile =  p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class];
            }
        }
        else
        {
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_fc_profile[cfg_idx];
            cmd = DRV_IOR(DsIrmPortCfg_t, DsIrmPortCfg_portLimitedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &old_profile_id));
            if (p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx])
            {
                p_sys_fc_dropthrd_profile = p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx];
            }
        }

        CTC_ERROR_RETURN(_sys_usw_qos_fc_profile_add_spool(lchip, p_fc->is_pfc, 0, p_sys_fc_profile, &fc_data, &p_sys_fc_profile_new));
        CTC_ERROR_RETURN(_sys_usw_qos_fc_profile_add_spool(lchip, p_fc->is_pfc, 1, p_sys_fc_dropthrd_profile, &fc_dropthrd_data, &p_sys_fc_dropthrd_profile_new));

        profile_id = p_sys_fc_profile_new->profile_id;
        dropthrd_profile_id = p_sys_fc_dropthrd_profile_new->profile_id;
    }

    if (p_fc->is_pfc)
    {
        if (DRV_FROM_TMM(lchip))
        {
            value = p_fc->xoff_thrd;
            step = DsIrmPortFlowControlThrdProfile_g_1_xoffThrd_f - DsIrmPortFlowControlThrdProfile_g_0_xoffThrd_f;
            cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DsIrmPortFlowControlThrdProfile_g_0_xoffThrd_f + p_fc->priority_class*step);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &value));

            value = p_fc->xon_thrd;
            cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DsIrmPortFlowControlThrdProfile_g_0_xonThrd_f + p_fc->priority_class*step);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &value));

            for(loop = 0; loop < 4; loop++)
            {
                step = DsIrmPortTcLimitedThrdProfile_g_1_portTcLimitedThrd_f - DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f;
                cmd = DRV_IOW(DsIrmPortTcLimitedThrdProfile_t, DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f+loop*step);
                value = p_fc->drop_thrd / 8;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx << 3 | p_fc->priority_class, cmd, &value));
            }
        }
        else
        {
            sal_memset(&ds_igr_port_tc_fc_profile, 0, sizeof(DsIrmPortTcFlowControlThrdProfile_m));

            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE, 1);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_DROPTH_PROFILE, 1);

            SetDsIrmPortTcFlowControlThrdProfile(V, portTcXoffThrd_f  , &ds_igr_port_tc_fc_profile, p_fc->xoff_thrd);
            SetDsIrmPortTcFlowControlThrdProfile(V, portTcXonThrd_f  , &ds_igr_port_tc_fc_profile, p_fc->xon_thrd);
            cmd = DRV_IOW(DsIrmPortTcFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (profile_id << 2), cmd, &ds_igr_port_tc_fc_profile));

            cmd = DRV_IOW(DsIrmPortStallCfg_t, DsIrmPortStallCfg_u_g1_0_portTcFlowControlThrdProfId_f + p_fc->priority_class);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &profile_id));
            p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][p_fc->priority_class] = p_sys_fc_profile_new;
            for(loop = 0; loop < 4; loop++)
            {
                step = DsIrmPortTcLimitedThrdProfile_g_1_portTcLimitedThrd_f - DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f;
                cmd = DRV_IOW(DsIrmPortTcLimitedThrdProfile_t, DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f+loop*step);
                value = p_fc->drop_thrd / 8;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dropthrd_profile_id << 2, cmd, &value));
            }
            /*1.old_profile_id = 0xF indicate flow control disabled, default is disable
              2.if pfc disabled, just store profile in software when add drop profile, then apply after pfc enabled
              3.if pfc enable, store profile in software, at the same time update profile id*/
            if(old_profile_id != 0XF)
            {
                cmd = DRV_IOW(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g1_portTcLimitedThrdProfId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (cfg_idx << 3) + p_fc->priority_class, cmd, &dropthrd_profile_id));
            }
            p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class] = p_sys_fc_dropthrd_profile_new;
        }
    }
    else
    {
        sal_memset(&ds_igr_port_fc_profile, 0, sizeof(DsIrmPortFlowControlThrdProfile_m));
        if(DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, cfg_idx, cmd, &ds_igr_port_fc_profile));
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xoffThrd_f  , &ds_igr_port_fc_profile, p_fc->xoff_thrd);
            SetDsIrmPortFlowControlThrdProfile(V, g_0_xonThrd_f  , &ds_igr_port_fc_profile, p_fc->xon_thrd);
            cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, cfg_idx, cmd, &ds_igr_port_fc_profile));

            for (loop = 0; loop < 4; loop++)
            {
                step = DsIrmPortLimitedThrdProfile_g_1_portLimitedThrd_f - DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f;
                cmd = DRV_IOW(DsIrmPortLimitedThrdProfile_t, DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f + loop*step);
                value = p_fc->drop_thrd / 8;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &value));
            }
        }
        else
        {
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE, 1);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE, 1);

            SetDsIrmPortFlowControlThrdProfile(V, portXoffThrd_f  , &ds_igr_port_fc_profile, p_fc->xoff_thrd);
            SetDsIrmPortFlowControlThrdProfile(V, portXonThrd_f  , &ds_igr_port_fc_profile, p_fc->xon_thrd);
            cmd = DRV_IOW(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, profile_id << 2, cmd, &ds_igr_port_fc_profile));

            field_id = p_fc->is_oobfc == 0 ? DsIrmPortStallCfg_portFlowControlThrdProfId_f
                                           : DsIrmPortStallCfg_u_g2_0_portFlowControlThrdProfId_f + lport % 8;
            cmd = DRV_IOW(DsIrmPortStallCfg_t,  field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &profile_id));

            if (p_fc->is_oobfc)
            {
                p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][lport % 8] = p_sys_fc_profile_new;
            }
            else
            {
                p_usw_queue_master[lchip]->p_fc_profile[cfg_idx] = p_sys_fc_profile_new;
            }
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE, 1);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE, 1);

            for (loop = 0; loop < 4; loop++)
            {
                step = DsIrmPortLimitedThrdProfile_g_1_portLimitedThrd_f - DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f;
                cmd = DRV_IOW(DsIrmPortLimitedThrdProfile_t, DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f + loop*step);
                value = p_fc->drop_thrd / 8;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dropthrd_profile_id << 2, cmd, &value));
            }

            if (p_fc->is_oobfc)
            {
                if (old_profile_id != 0XF)
                {
                    cmd = DRV_IOW(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g2_portLimitedThrdProfId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx << 3 | lport % 8, cmd, &dropthrd_profile_id));
                }
                p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport % 8] = p_sys_fc_dropthrd_profile_new;
            }
            else
            {
                if (old_profile_id != 0XF)
                {
                    cmd = DRV_IOW(DsIrmPortCfg_t, DsIrmPortCfg_portLimitedThrdProfId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &dropthrd_profile_id));
                }
                p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx] = p_sys_fc_dropthrd_profile_new;
            }
        }
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_fc_get_profile(uint8 lchip, ctc_qos_resrc_fc_t *p_fc)
{
    uint32 cfg_idx = 0;
    uint32 port_type = 0;
    uint16 chan_id = 0;
    uint16 lport = 0;
    sys_qos_fc_profile_t *p_sys_fc_profile = NULL;
    sys_qos_fc_profile_t *p_dropthrd_fc_profile = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if (DRV_IS_TMG(lchip) && p_fc->is_oobfc)
    {
        return CTC_E_NOT_SUPPORT;
    }
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_fc->gport, lchip, lport);
    CTC_MAX_VALUE_CHECK(p_fc->priority_class, 7);

    dmps_port_info.gport = p_fc->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if (((SYS_DMPS_NETWORK_PORT == port_type) || (SYS_DMPS_CPUMAC_NETWORK_PORT == port_type)) && p_fc->is_oobfc)
    {
        return sys_usw_qos_oobfc_get_profile(lchip, p_fc);
    }
    CTC_ERROR_RETURN(_sys_usw_get_channel_by_port(lchip, p_fc->gport, &chan_id));
    if (chan_id == SYS_DMPS_INVALID_CHAN_ID)
    {
        return CTC_E_INVALID_PARAM;
    }

    lport = CTC_MAP_GPORT_TO_LPORT(p_fc->gport);
    if(MCHIP_QOS(lchip)->qos_resrc_fc_get_profile)
    {
        cfg_idx = p_fc->is_oobfc ? lport : chan_id;
        return MCHIP_QOS(lchip)->qos_resrc_fc_get_profile(lchip, cfg_idx, p_fc);
    }
    else if(p_fc->is_oobfc)/*ingress oobfc*/
    {
        if(p_fc->is_pfc)
        {
            cfg_idx = lport - CTC_MAP_GPORT_TO_LPORT(p_usw_queue_master[lchip]->oobfc_group_info.port_base) + SYS_MAX_OOBFC_PORT_CFG_BASE;/*[64,96)*/
            CTC_VALUE_RANGE_CHECK(cfg_idx, 64, 95);
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][p_fc->priority_class];
            p_dropthrd_fc_profile = p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class];
        }
        else
        {
            cfg_idx = lport / 8 + SYS_MAX_OOBFC_PORT_CFG_BASE;
            CTC_VALUE_RANGE_CHECK(cfg_idx, 64, 95);
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][lport%8];
            p_dropthrd_fc_profile = p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport%8];
        }
    }
    else
    {
        cfg_idx = chan_id;/*[0,64)*/
        if (p_fc->is_pfc)
        {
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][p_fc->priority_class];
            p_dropthrd_fc_profile = p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][p_fc->priority_class];
        }
        else
        {
            p_sys_fc_profile = p_usw_queue_master[lchip]->p_fc_profile[cfg_idx];
            p_dropthrd_fc_profile = p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx];
        }
    }
    p_fc->xon_thrd = p_sys_fc_profile->xon;
    p_fc->xoff_thrd = p_sys_fc_profile->xoff;
    p_fc->drop_thrd = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD);
    if (p_dropthrd_fc_profile)
    {
        p_fc->drop_thrd = p_dropthrd_fc_profile->thrd;
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_fc_get_profile_from_asic(uint8 lchip, uint8 is_pfc, sys_qos_fc_profile_t *p_sys_fc_profile)
{
    uint8 index = 0;
    uint32 cmd = 0;
    DsIrmPortTcFlowControlThrdProfile_m ds_igr_port_tc_fc_profile;
    DsIrmPortFlowControlThrdProfile_m ds_igr_port_fc_profile;

    if (is_pfc)
    {
        index = (p_sys_fc_profile->profile_id << 2);
        sal_memset(&ds_igr_port_tc_fc_profile, 0, sizeof(DsIrmPortTcFlowControlThrdProfile_m));
        cmd = DRV_IOR(DsIrmPortTcFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_igr_port_tc_fc_profile));

        p_sys_fc_profile->xoff = GetDsIrmPortTcFlowControlThrdProfile(V, portTcXoffThrd_f, &ds_igr_port_tc_fc_profile);
        p_sys_fc_profile->xon = GetDsIrmPortTcFlowControlThrdProfile(V, portTcXonThrd_f, &ds_igr_port_tc_fc_profile);
    }
    else
    {
        index = (p_sys_fc_profile->profile_id << 2);
        sal_memset(&ds_igr_port_fc_profile, 0, sizeof(DsIrmPortFlowControlThrdProfile_m));
        cmd = DRV_IOR(DsIrmPortFlowControlThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_igr_port_fc_profile));

        p_sys_fc_profile->xoff = GetDsIrmPortFlowControlThrdProfile(V, portXoffThrd_f, &ds_igr_port_fc_profile);
        p_sys_fc_profile->xon = GetDsIrmPortFlowControlThrdProfile(V, portXonThrd_f, &ds_igr_port_fc_profile);
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_oobfc_get_profile_from_asic(uint8 lchip, sys_qos_oobfc_profile_t *p_sys_oobfc_profile)
{
    uint8 index = 0;
    uint8 loop = 0;
    uint32 cmd = 0;
    DsErmPortFcCfg_m ds_egr_port_tc_fc_profile;

    sal_memset(&ds_egr_port_tc_fc_profile, 0, sizeof(ds_egr_port_tc_fc_profile));

    for (loop = 0; loop < 8; loop++)
    {
        index = p_sys_oobfc_profile->index.index << 3 | loop;
        cmd = DRV_IOR(DsErmPortFcCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_egr_port_tc_fc_profile));
        p_sys_oobfc_profile->xoff[loop] = GetDsErmPortFcCfg(V, xoffThrd_f, &ds_egr_port_tc_fc_profile);
        p_sys_oobfc_profile->xon[loop] = GetDsErmPortFcCfg(V, xonThrd_f, &ds_egr_port_tc_fc_profile);
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_fc_get_dropthrd_profile_from_asic(uint8 lchip, uint8 is_pfc, sys_qos_fc_profile_t *p_sys_fc_profile)
{
    uint8 index = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    if (is_pfc)
    {
        index = (p_sys_fc_profile->profile_id << 2);
        cmd = DRV_IOR(DsIrmPortTcLimitedThrdProfile_t, DsIrmPortTcLimitedThrdProfile_g_0_portTcLimitedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
        p_sys_fc_profile->thrd = value * 8;
    }
    else
    {
        index = (p_sys_fc_profile->profile_id << 2);
        cmd = DRV_IOR(DsIrmPortLimitedThrdProfile_t, DsIrmPortLimitedThrdProfile_g_0_portLimitedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
        p_sys_fc_profile->thrd = value * 8;
    }
    p_sys_fc_profile->type = 1;

    return CTC_E_NONE;
}


STATIC uint32
_sys_usw_queue_drop_wtd_hash_make_profile(sys_queue_drop_wtd_profile_t* p_prof)
{
    return ctc_hash_caculate(sizeof(DsErmQueueLimitedThrdProfile_m) * 8, p_prof->p_ds);
}

/**
 @brief Queue drop hash comparison hook.
*/
STATIC bool
_sys_usw_queue_drop_wtd_hash_cmp_profile(sys_queue_drop_wtd_profile_t* p_prof1,
                                           sys_queue_drop_wtd_profile_t* p_prof2)
{
    uint32 cmd = 0;
    uint8 loop = 0;
    uint8 temp_value = 0;
    uint8 lchip = 0;
    DsErmQueueLimitedThrdProfile_m ds[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
    void* p_ds = &ds;
    uint16 size = sizeof(ds);

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (!p_prof1 || !p_prof2 || !p_prof2->p_ds)
    {
        return FALSE;
    }

    if (0xFF == p_prof1->profile_id)/*for spool add error rollback*/
    {
        return TRUE;
    }

    lchip = p_prof2->lchip;
    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
    for(loop = 0; loop < p_prof1->cng_num; loop++)
    {
        temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (loop + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-p_prof1->cng_num)):0;
        if (DRV_E_NONE != DRV_IOCTL(lchip, p_prof1->profile_id << 2 | temp_value, cmd, &ds[temp_value]))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [ASIC] Hardware operation failed \n");
            return CTC_E_HW_FAIL;
        }
    }

    /*before tmm only, wtd dynamic&static all use 8 profile to compare*/
    if (!sal_memcmp(p_ds, p_prof2->p_ds, size))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_usw_queue_drop_wtd_alloc_profileId(sys_queue_drop_wtd_profile_t* p_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = p_usw_queue_master[*p_lchip]->opf_type_queue_drop_wtd;
    opf.pool_index = 0;
    if (CTC_WB_STATUS(*p_lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, p_node->profile_id));
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
        p_node->profile_id = value_32;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_drop_wtd_free_profileId(sys_queue_drop_wtd_profile_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_drop_wtd;
    opf.pool_index = 0;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

uint32
_sys_usw_queue_drop_wred_hash_make_profile(sys_queue_drop_wred_profile_t* p_prof)
{
    return ctc_hash_caculate(sizeof(DsErmAqmQueueThrdProfile_m), p_prof->p_ds);
}

/**
 @brief Queue drop hash comparison hook.
*/
bool
_sys_usw_queue_drop_wred_hash_cmp_profile(sys_queue_drop_wred_profile_t* p_prof1,
                                           sys_queue_drop_wred_profile_t* p_prof2)
{
    uint32 cmd = 0;
    DsErmAqmQueueThrdProfile_m ds;
    void* p_ds = &ds;
    uint8 size = sizeof(ds);
    uint8 lchip = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (!p_prof1 || !p_prof2 || !p_prof2->p_ds || p_prof1->dp_id != p_prof2->dp_id)
    {
        return FALSE;
    }

    if (0xFFF == p_prof1->profile_id)/*for spool add error rollback*/
    {
        return TRUE;
    }

    lchip = SYS_PP_BASE(p_prof1->lchip) + (p_prof1->dp_id  >> 1);
    sal_memset(&ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
    if (DRV_E_NONE != DRV_IOCTL(lchip, p_prof1->profile_id, DRV_CMD_DP_EN(cmd, (p_prof1->dp_id & 0x1)), &ds))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " [ASIC] Hardware operation failed \n");
        return CTC_E_HW_FAIL;
    }
    if (!sal_memcmp(p_ds, p_prof2->p_ds, size))
    {
        return TRUE;
    }

    return FALSE;
}

int32
_sys_usw_queue_drop_wred_alloc_profileId(sys_queue_drop_wred_profile_t* p_node, uint8* p_lchip)
{
    uint32 value_32 = 0;
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_drop_wred;
    opf.pool_index = DRV_FROM_AT(*p_lchip) ? p_node->dp_id : 0;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(*p_lchip, &opf, 1, &value_32));
    p_node->profile_id = value_32;

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_wred_restore_profileId(sys_queue_drop_wred_profile_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_drop_wred;
    opf.pool_index = DRV_FROM_AT(*p_lchip) ? p_node->dp_id : 0;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_wred_free_profileId(sys_queue_drop_wred_profile_t* p_node, uint8* p_lchip)
{
    sys_usw_opf_t opf;

    CTC_PTR_VALID_CHECK(p_node);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type  = p_usw_queue_master[*p_lchip]->opf_type_queue_drop_wred;
    opf.pool_index = DRV_FROM_AT(*p_lchip) ? p_node->dp_id : 0;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(*p_lchip, &opf, 1, p_node->profile_id));

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_wtd_profile_add_spool(uint8 lchip, sys_queue_drop_wtd_profile_t* p_sys_profile_old,
                                                          sys_queue_drop_wtd_profile_t* p_sys_profile_new,
                                                          sys_queue_drop_wtd_profile_t** pp_sys_profile_get)
{
    ctc_spool_t* p_profile_pool    = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_profile_new);

    /*if use new date to replace old data, profile_id will not change*/
    if (p_sys_profile_old)
    {
        if (TRUE == _sys_usw_queue_drop_wtd_hash_cmp_profile(p_sys_profile_old, p_sys_profile_new))
        {
            *pp_sys_profile_get = p_sys_profile_old;

            return CTC_E_NONE;
        }
    }

    p_profile_pool = p_usw_queue_master[lchip]->p_drop_wtd_profile_pool;
    CTC_ERROR_RETURN(ctc_spool_add(p_profile_pool,
                           p_sys_profile_new,
                           p_sys_profile_old,
                           pp_sys_profile_get));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile_id = %d\n",  (*pp_sys_profile_get)->profile_id);

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_wred_profile_add_spool(uint8 lchip, sys_queue_drop_wred_profile_t* p_sys_profile_old,
                                                          sys_queue_drop_wred_profile_t* p_sys_profile_new,
                                                          sys_queue_drop_wred_profile_t** pp_sys_profile_get)
{
    ctc_spool_t* p_profile_pool    = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_profile_new);

    /*if use new date to replace old data, profile_id will not change*/
    if (p_sys_profile_old)
    {
        if (TRUE == _sys_usw_queue_drop_wred_hash_cmp_profile(p_sys_profile_old, p_sys_profile_new))
        {
            *pp_sys_profile_get = p_sys_profile_old;

            return CTC_E_NONE;
        }
    }

    p_profile_pool = p_usw_queue_master[lchip]->p_drop_wred_profile_pool;
    CTC_ERROR_RETURN(ctc_spool_add(p_profile_pool,
                           p_sys_profile_new,
                           p_sys_profile_old,
                           pp_sys_profile_get));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile_id = %d\n",  (*pp_sys_profile_get)->profile_id);

    return CTC_E_NONE;
}

int32
sys_usw_queue_get_sc_tc(uint8 lchip, sys_queue_node_t* p_sys_queue, uint8* sc, uint8* tc)
{
    uint8 is_mcast = 0;
    uint8 value = 0;
    uint16 channel = 0;
    uint8 index = 0;
    uint8 is_network = 0;
    uint32 cmd = 0;
    uint16 lport = 0;
    uint16 key_index = 0;
    tbl_entry_t   tcam_key;
    uint32 dest_map = 0;
    DsQueueMapTcamKey_m   QueueMapTcamKey;
    DsQueueMapTcamKey_m   QueueMapTcamMask;
    CTC_PTR_VALID_CHECK(p_sys_queue);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&QueueMapTcamKey, 0 , sizeof(QueueMapTcamKey));
    sal_memset(&QueueMapTcamMask, 0 , sizeof(QueueMapTcamMask));
    if(p_sys_queue->queue_id >=  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT))
    {
        key_index = (p_sys_queue->queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT))/MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        tcam_key.data_entry = (uint32*)(&QueueMapTcamKey);
        tcam_key.mask_entry = (uint32*)(&QueueMapTcamMask);
        cmd = DRV_IOR(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &tcam_key));
        dest_map = GetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamKey);
        is_mcast = (dest_map &0x40000) ? 1 :0;
    }
    if(DRV_FROM_TM(lchip))
    {
        value = ((SYS_IS_NETWORK_CTL_QUEUE(p_sys_queue->queue_id)) && ((p_sys_queue->queue_id % 4) < 2));
    }
    else
    {
        value = ((SYS_IS_NETWORK_CTL_QUEUE(p_sys_queue->queue_id)) && ((p_sys_queue->queue_id % 4) < 1));
    }
    if(((value)||(p_usw_queue_master[lchip]->enq_mode && is_mcast)) &&
        p_usw_queue_master[lchip]->egs_pool[CTC_QOS_EGS_RESRC_SPAN_POOL].egs_congest_level_num)
    {
        *sc = CTC_QOS_EGS_RESRC_SPAN_POOL;
    }
    else if(SYS_IS_CPU_QUEUE(p_sys_queue->queue_id))
    {
        *sc = CTC_QOS_EGS_RESRC_CONTROL_POOL;
    }
    else
    {
        CTC_ERROR_RETURN(sys_usw_get_channel_by_queue_id(lchip, p_sys_queue->queue_id, &channel));
        if(channel == MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0) || channel == MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1)
            || channel == MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2) || channel == MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC3))
        {
            if (MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
            {
                index = (channel - (channel > MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1) ? (MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2) - 2 ) : MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0)));
                MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,index,&lport,&is_network);
                if(!is_network)
                {
                    *sc = CTC_QOS_EGS_RESRC_CONTROL_POOL;
                }
                else
                {
                    *sc = CTC_QOS_EGS_RESRC_DEFAULT_POOL;
                }
            }
        }
        else
        {
            *sc = CTC_QOS_EGS_RESRC_DEFAULT_POOL;
        }
    }
    *tc = p_sys_queue->offset;

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_write_profile_to_asic(uint8 lchip, uint8 wred_mode,uint8 is_dynamic, ctc_qos_drop_array drop_arraw,
                                             sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;
    uint8  sc = 0;
    uint8  tc = 0;
    uint8  level_num = 0;
    uint8  cng_level = 0;
    uint16 index = 0;
    uint8  temp_value = 0;
    uint8  dp = 0;
    uint8  step = 0;
    uint8 drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    ds_t ds;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /* config db */
    if (wred_mode)
    {
        uint32 max_len_range[4] = {drop_arraw[cng_level].drop.max_th[0], drop_arraw[cng_level].drop.max_th[1], 
                                   drop_arraw[cng_level].drop.max_th[2], drop_arraw[cng_level].drop.max_th[3]};
        uint32 min_len_range[4] = {drop_arraw[cng_level].drop.min_th[0], drop_arraw[cng_level].drop.min_th[1], 
                                   drop_arraw[cng_level].drop.min_th[2], drop_arraw[cng_level].drop.min_th[3]};
        uint8  drop_prob[4]     = {drop_arraw[cng_level].drop.drop_prob[0], drop_arraw[cng_level].drop.drop_prob[1], 
                                   drop_arraw[cng_level].drop.drop_prob[2], drop_arraw[cng_level].drop.drop_prob[3]};

        sal_memset(ds, 0, sizeof(ds));
        step = DsErmAqmQueueThrdQuantProfile_g_1_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
        for (dp = 0; dp < 4; dp++)
        {
            SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f + step*dp, &ds, max_len_range[dp] / 8);
            SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f + step*dp, &ds, min_len_range[dp] / 8);
            SetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f + step*dp, &ds, drop_prob[dp]);
        }
        cmd = DRV_IOW(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->node[0].drop_wred_profile_id, cmd, &ds));

        if(DRV_FROM_TMM(lchip))
        {
            /*TMM prob quantification*/
            sal_memset(ds, 0, sizeof(ds));
            step = DsErmAqmQueueThrdQuantProfile_g_1_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
            for (dp = 0; dp < 4; dp++)
            {
                for(index = 0; index < 7; index++)
                {
                    SetDsErmAqmQueueThrdQuantProfile(V, g_0_wredAvgMaxLen_f + step*index, &ds, (min_len_range[dp] + ((max_len_range[dp] - min_len_range[dp]) / 8)*(index + 1)) / 8);
                    SetDsErmAqmQueueThrdQuantProfile(V, g_0_wredProbFactor_f + step*index, &ds, (drop_prob[dp] / 8)*(index + 1));
                }
                cmd = DRV_IOW(DsErmAqmQueueThrdQuantProfile_t, DRV_ENTRY_FLAG);
                index = ((p_sys_queue->node[0].drop_wred_profile_id) << 2) + dp;
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
            }
        }

    }
    else if(is_dynamic == 0)
    {
        sys_usw_queue_get_sc_tc(lchip, p_sys_queue, &sc, &tc);
        level_num = p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num;
        sal_memset(&ds, 0, sizeof(ds));
        for (cng_level = 0; cng_level < level_num; cng_level++)
        {
            sal_memset(ds, 0, sizeof(ds));
            temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cng_level + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-level_num)):0;
            SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f, &ds, drop_arraw[cng_level].drop.max_th[0] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f, &ds, drop_arraw[cng_level].drop.max_th[1] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f, &ds, drop_arraw[cng_level].drop.max_th[2] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f, &ds, drop_arraw[cng_level].drop.max_th[3] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[0] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[1] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[2] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[3] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedAutoEn_f , &ds, 0);
            SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedAutoEn_f , &ds, 0);
            SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedAutoEn_f , &ds, 0);
            SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedAutoEn_f , &ds, 0);
            cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_queue->drop_wtd_profile_id << 2 | temp_value);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
    }
    else if(is_dynamic == 1)
    {
        sal_memset(&ds, 0, sizeof(ds));
        SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[0] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[1] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[2] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds, drop_arraw[cng_level].drop.ecn_th[3] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f , &ds, drop_factor[drop_arraw[cng_level].drop.drop_factor[0]]);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f , &ds, drop_factor[drop_arraw[cng_level].drop.drop_factor[1]]);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f , &ds, drop_factor[drop_arraw[cng_level].drop.drop_factor[2]]);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f , &ds, drop_factor[drop_arraw[cng_level].drop.drop_factor[3]]);
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedAutoEn_f , &ds, 1);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedAutoEn_f , &ds, 1);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedAutoEn_f , &ds, 1);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedAutoEn_f , &ds, 1);
        index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_queue->drop_wtd_profile_id << 2);
        cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_read_profile_from_asic(uint8 lchip, uint8 wred_mode,
                                             sys_queue_node_t* p_sys_queue,
                                             sys_queue_drop_profile_t* p_sys_profile)
{
    uint32 cmd = 0;
    uint8  sc = 0;
    uint8  tc = 0;
    uint8  level_num = 0;
    uint8  cng_level = 0;
    uint16  index = 0;
    uint32 value = 0;
    uint8 temp_value = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_queue);
    CTC_PTR_VALID_CHECK(p_sys_profile);

    /* get queue sc */
    /*cmd = DRV_IOR(DsEgrResrcCtl_t, DsEgrResrcCtl_mappedSc_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_sys_queue->queue_id, cmd, &sc));
    */
    if(!wred_mode)
    {
        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedAutoEn_f);
        index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_profile->p_drop_wtd_profile->profile_id << 2);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
    }
    /* config db */
    if (wred_mode)
    {
        ds_t ds;
        sal_memset(&ds, 0, sizeof(ds));
        cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) + p_sys_queue->pp_id, p_sys_profile->p_drop_wred_profile->profile_id, DRV_CMD_DP_EN(cmd, p_sys_queue->dp_id), &ds));
        sal_memcpy(p_sys_profile->p_drop_wred_profile->p_ds, ds, sizeof(ds));
    }
    else if(value == 0)
    {
        DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
        sal_memset(&ds_que_thrd_profile, 0, sizeof(ds_que_thrd_profile));
        sys_usw_queue_get_sc_tc(lchip, p_sys_queue, &sc, &tc);
        level_num = p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num;
        for (cng_level = 0; cng_level < level_num; cng_level++)
        {
            temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cng_level + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-level_num)):0;
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : ((p_sys_profile->p_drop_wtd_profile->profile_id << 2) + temp_value);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile[temp_value]));
        }
        p_sys_profile->p_drop_wtd_profile->cng_num = level_num;
        sal_memcpy(p_sys_profile->p_drop_wtd_profile->p_ds, &ds_que_thrd_profile, sizeof(ds_que_thrd_profile));
    }
    else if(value == 1)
    {
        DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile;
        sal_memset(&ds_que_thrd_profile, 0, sizeof(DsErmQueueLimitedThrdProfile_m));
        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_profile->p_drop_wtd_profile->profile_id << 2);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
        p_sys_profile->p_drop_wtd_profile->cng_num = 1;
        sal_memcpy(p_sys_profile->p_drop_wtd_profile->p_ds, &ds_que_thrd_profile, sizeof(ds_que_thrd_profile));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_drop_write_asic(uint8 lchip, uint8 wred_mode, uint8 wred_weight, sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 field_val = 0;
    uint8  step = 0;
    DsErmQueueCfg_m erm_queue_cfg;
    DsErmAqmQueueCfg_m erm_aqm_cfg;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));
    sal_memset(&erm_aqm_cfg, 0, sizeof(DsErmAqmQueueCfg_m));

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        if (wred_mode)
        {
            field_val = p_sys_queue->node[0].drop_wred_profile_id;
            index = p_sys_queue->queue_id >> 2;
            cmd = DRV_IOW(DsErmAqmQueueThrdProfileId_t, DsErmAqmQueueThrdProfileId_g_0_aqmThrdProfileId_f + (p_sys_queue->queue_id&0x3));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));

            step = DsErmAqmQueueCfg_g_1_ewmaWeightFactor_f - DsErmAqmQueueCfg_g_0_ewmaWeightFactor_f;
            cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
            SetDsErmAqmQueueCfg(V, g_0_avgQueueLenResetEn_f + step * (p_sys_queue->queue_id & 0x3), &erm_aqm_cfg, 1);
            SetDsErmAqmQueueCfg(V, g_0_ewmaWeightFactor_f + step * (p_sys_queue->queue_id & 0x3), &erm_aqm_cfg, wred_weight ? wred_weight : 1);
            cmd = DRV_IOW(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
        }
        return CTC_E_NONE;
    }

    if (wred_mode && (SYS_IS_NETWORK_BASE_QUEUE(p_sys_queue->queue_id) || SYS_IS_EXT_QUEUE(p_sys_queue->queue_id)))
    {
        index = (p_sys_queue->queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC))
                     ?  p_sys_queue->queue_id : (p_sys_queue->queue_id - (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)- MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC)));

        cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
        SetDsErmAqmQueueCfg(V, queueThrdProfId_f, &erm_aqm_cfg, p_sys_queue->node[0].drop_wred_profile_id);
        SetDsErmAqmQueueCfg(V, avgQueueLenResetEn_f, &erm_aqm_cfg, 1);
        SetDsErmAqmQueueCfg(V, ewmaWeightFactor_f, &erm_aqm_cfg, wred_weight ? wred_weight : 1);
        cmd = DRV_IOW(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
    }
    else if(wred_mode == 0)
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->queue_id, cmd, &erm_queue_cfg));
        SetDsErmQueueCfg(V, queueLimitedThrdProfId_f, &erm_queue_cfg, p_sys_queue->drop_wtd_profile_id);
        cmd = DRV_IOW(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->queue_id, cmd, &erm_queue_cfg));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_read_asic(uint8 lchip, uint8 wred_mode, sys_queue_node_t *p_queue_node,
                                                 sys_queue_drop_profile_t* p_sys_profile, uint8* hw_valid)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint16 queue_id = p_queue_node->queue_id;
    DsErmQueueCfg_m erm_queue_cfg;
    DsErmAqmQueueCfg_m erm_aqm_cfg;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (MCHIP_QOS(lchip)->qos_queue_drop_read_asic)
    {
        return MCHIP_QOS(lchip)->qos_queue_drop_read_asic(lchip, wred_mode, p_queue_node, p_sys_profile, hw_valid);
    }

    sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));
    sal_memset(&erm_aqm_cfg, 0, sizeof(DsErmAqmQueueCfg_m));

    if (wred_mode && (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id)))
    {
        index = (queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC))
                     ?  queue_id : (queue_id - (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)- MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC)));

        cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
        p_sys_profile[0].p_drop_wred_profile->profile_id = GetDsErmAqmQueueCfg(V, queueThrdProfId_f, &erm_aqm_cfg);
        *hw_valid = 1;

    }
    else if(wred_mode == 0)
    {
        index = queue_id;
        cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
        p_sys_profile[0].p_drop_wtd_profile->profile_id = GetDsErmQueueCfg(V, queueLimitedThrdProfId_f, &erm_queue_cfg);
        *hw_valid = 1;
    }

    return CTC_E_NONE;
}
STATIC int32
_sys_usw_queue_drop_clear_asic(uint8 lchip, uint8 wred_mode, sys_queue_node_t* p_sys_queue_node)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 field_val = 0;
    DsErmQueueCfg_m erm_queue_cfg;
    DsErmAqmQueueCfg_m erm_aqm_cfg;
    uint16 queue_id = p_sys_queue_node->queue_id;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));
    sal_memset(&erm_aqm_cfg, 0, sizeof(DsErmAqmQueueCfg_m));

    if (wred_mode)
    {
        if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            cmd = DRV_IOW(DsErmAqmQueueThrdProfileId_t, DsErmAqmQueueThrdProfileId_g_0_aqmThrdProfileId_f + (queue_id&0x3));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id >> 2, cmd, &field_val));
        }
        else
        {
            index = (queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC))
                     ?  queue_id : (queue_id - (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)- MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC)));
            cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
            field_val = MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM);
            SetDsErmAqmQueueCfg(V, queueThrdProfId_f, &erm_aqm_cfg, field_val);
            cmd = DRV_IOW(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
        }
    }
    else
    {
        index = queue_id;
        cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
        field_val = MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM);
        SetDsErmQueueCfg(V, queueLimitedThrdProfId_f, &erm_queue_cfg, field_val);
        cmd = DRV_IOW(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_drop_add_profile(uint8 lchip, uint8 wred_mode, uint8 is_dynamic,ctc_qos_drop_array drop_arraw,
                                      sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;
    uint8  cng_level = 0;
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_sys_queue);

    /* config db */
    if (wred_mode)
    {
        uint8 step = 0;
        uint8 dp = 0;
        sys_queue_drop_wred_profile_t  sys_wred_profile;
        sys_queue_drop_wred_profile_t  sys_wred_profile_new;
        sys_queue_drop_wred_profile_t* sys_wred_profile_old = NULL;
        sys_queue_drop_wred_profile_t* p_sys_wred_profile_get = NULL;
        DsErmAqmQueueThrdProfile_m ds_old;
        DsErmAqmQueueThrdProfile_m ds_new;
        uint32 max_len_range[4] = {drop_arraw[cng_level].drop.max_th[0], drop_arraw[cng_level].drop.max_th[1], 
                                   drop_arraw[cng_level].drop.max_th[2], drop_arraw[cng_level].drop.max_th[3]};
        uint32 min_len_range[4] = {drop_arraw[cng_level].drop.min_th[0], drop_arraw[cng_level].drop.min_th[1], 
                                   drop_arraw[cng_level].drop.min_th[2], drop_arraw[cng_level].drop.min_th[3]};
        uint8  drop_prob[4]     = {drop_arraw[cng_level].drop.drop_prob[0], drop_arraw[cng_level].drop.drop_prob[1], 
                                   drop_arraw[cng_level].drop.drop_prob[2], drop_arraw[cng_level].drop.drop_prob[3]};

        sal_memset(&sys_wred_profile_new, 0, sizeof(sys_wred_profile_new));
        sal_memset(&sys_wred_profile, 0, sizeof(sys_wred_profile));
        sal_memset(&ds_old, 0, sizeof(ds_old));
        sal_memset(&ds_new, 0, sizeof(ds_new));

        if (MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM) != p_sys_queue->node[0].drop_wred_profile_id)
        {
            cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, p_sys_queue->node[0].drop_wred_profile_id, cmd, &ds_old);

            /*old profile*/
            sys_wred_profile.profile_id = p_sys_queue->node[0].drop_wred_profile_id;
            sys_wred_profile.lchip = lchip;
            sys_wred_profile.p_ds = &ds_old;
            sys_wred_profile_old = &sys_wred_profile;
        }

        /*AT DsAqmQueueThrdProfile -> DsErmAqmQueueThrdProfile, change tbl name in drv*/
        step = DsErmAqmQueueThrdQuantProfile_g_1_wredAvgMaxLen_f - DsErmAqmQueueThrdQuantProfile_g_0_wredAvgMaxLen_f;
        for (dp = 0; dp < 4; dp++)
        {
            SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f + step*dp, &ds_new, max_len_range[dp] / 8);
            SetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f + step*dp, &ds_new, min_len_range[dp] / 8);
            SetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f + step*dp, &ds_new, drop_prob[dp]);
        }

        /*new profile*/        
        sys_wred_profile_new.lchip = lchip;
        sys_wred_profile_new.p_ds = &ds_new;

        CTC_ERROR_RETURN(_sys_usw_queue_drop_wred_profile_add_spool(lchip, sys_wred_profile_old, &sys_wred_profile_new, &p_sys_wred_profile_get));
        p_sys_queue->node[0].drop_wred_profile_id = p_sys_wred_profile_get->profile_id;
    }
    else if(is_dynamic == 0)
    {
        uint32 index = 0;
        uint32 temp_value = 0;
        uint8  sc = 0;
        uint8  tc = 0;
        uint8  level_num = 0;
        sys_queue_drop_wtd_profile_t  sys_wtd_profile_old;
        sys_queue_drop_wtd_profile_t  sys_wtd_profile_new;
        sys_queue_drop_wtd_profile_t* p_sys_wtd_profile_get = NULL;
        DsErmQueueLimitedThrdProfile_m ds_old[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
        DsErmQueueLimitedThrdProfile_m ds_new[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];

        sal_memset(&sys_wtd_profile_new, 0, sizeof(sys_wtd_profile_new));
        sal_memset(&sys_wtd_profile_old, 0, sizeof(sys_wtd_profile_old));
        sal_memset(&ds_old, 0, sizeof(ds_old));
        sal_memset(&ds_new, 0, sizeof(ds_new));

        sys_usw_queue_get_sc_tc(lchip, p_sys_queue, &sc, &tc);
        level_num = p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num;
        if (level_num == 0)
        {
            return CTC_E_INVALID_PARAM;
        }
        
        for (cng_level = 0; cng_level < level_num; cng_level++)
        {
            temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cng_level + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-level_num)):0;

            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_queue->drop_wtd_profile_id << 2 | temp_value);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_old[temp_value]));

            SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f, &ds_new[temp_value], drop_arraw[cng_level].drop.max_th[0] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f, &ds_new[temp_value], drop_arraw[cng_level].drop.max_th[1] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f, &ds_new[temp_value], drop_arraw[cng_level].drop.max_th[2] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f, &ds_new[temp_value], drop_arraw[cng_level].drop.max_th[3] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_new[temp_value], drop_arraw[cng_level].drop.ecn_th[0] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_new[temp_value], drop_arraw[cng_level].drop.ecn_th[1] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_new[temp_value], drop_arraw[cng_level].drop.ecn_th[2] / 8);
            SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_new[temp_value], drop_arraw[cng_level].drop.ecn_th[3] / 8);
        }
        /*old profile*/
        sys_wtd_profile_old.profile_id = p_sys_queue->drop_wtd_profile_id;
        sys_wtd_profile_old.lchip = lchip;
        sys_wtd_profile_old.cng_num = level_num;
        sys_wtd_profile_old.p_ds = &ds_old;
        
        /*new profile*/        
        sys_wtd_profile_new.lchip = lchip;
        sys_wtd_profile_new.cng_num = level_num;
        sys_wtd_profile_new.p_ds = &ds_new;

        CTC_ERROR_RETURN(_sys_usw_queue_drop_wtd_profile_add_spool(lchip, &sys_wtd_profile_old, &sys_wtd_profile_new, &p_sys_wtd_profile_get));
        p_sys_queue->drop_wtd_profile_id = p_sys_wtd_profile_get->profile_id;
    }
    else if(is_dynamic == 1)
    {
        uint32 index = 0;
        sys_queue_drop_wtd_profile_t  sys_wtd_profile_old;
        sys_queue_drop_wtd_profile_t  sys_wtd_profile_new;
        sys_queue_drop_wtd_profile_t* p_sys_wtd_profile_get = NULL;
        DsErmQueueLimitedThrdProfile_m ds_old[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
        DsErmQueueLimitedThrdProfile_m ds_new[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
        uint8  drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};

        sal_memset(&sys_wtd_profile_new, 0, sizeof(sys_wtd_profile_new));
        sal_memset(&sys_wtd_profile_old, 0, sizeof(sys_wtd_profile_old));
        sal_memset(&ds_old, 0, sizeof(ds_old));
        sal_memset(&ds_new, 0, sizeof(ds_new));

        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        index = DRV_FROM_TMM(lchip) ? p_sys_queue->queue_id : (p_sys_queue->drop_wtd_profile_id << 2);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_old[0]));

        SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_new[0], drop_arraw[cng_level].drop.ecn_th[0] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_new[0], drop_arraw[cng_level].drop.ecn_th[1] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_new[0], drop_arraw[cng_level].drop.ecn_th[2] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_new[0], drop_arraw[cng_level].drop.ecn_th[3] / 8);
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f , &ds_new[0], drop_factor[drop_arraw[cng_level].drop.drop_factor[0]]);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f , &ds_new[0], drop_factor[drop_arraw[cng_level].drop.drop_factor[1]]);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f , &ds_new[0], drop_factor[drop_arraw[cng_level].drop.drop_factor[2]]);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f , &ds_new[0], drop_factor[drop_arraw[cng_level].drop.drop_factor[3]]);
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedAutoEn_f , &ds_new[0], 1);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedAutoEn_f , &ds_new[0], 1);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedAutoEn_f , &ds_new[0], 1);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedAutoEn_f , &ds_new[0], 1);

        /*old profile*/
        sys_wtd_profile_old.profile_id = p_sys_queue->drop_wtd_profile_id;
        sys_wtd_profile_old.lchip = lchip;
        sys_wtd_profile_old.cng_num = 1;
        sys_wtd_profile_old.p_ds = &ds_old;
        
        /*new profile*/        
        sys_wtd_profile_new.lchip = lchip;
        sys_wtd_profile_new.cng_num = 1;
        sys_wtd_profile_new.p_ds = &ds_new;
        CTC_ERROR_RETURN(_sys_usw_queue_drop_wtd_profile_add_spool(lchip, &sys_wtd_profile_old, &sys_wtd_profile_new, &p_sys_wtd_profile_get));
        p_sys_queue->drop_wtd_profile_id = p_sys_wtd_profile_get->profile_id;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_drop_remove_profile(uint8 lchip, uint8 wred_mode, sys_queue_node_t* p_sys_queue)
{
    uint32 cmd = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_queue);

    if (wred_mode)
    {
        if ((!DRV_FROM_TMM(lchip) && MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM) != p_sys_queue->node[0].drop_wred_profile_id)
            || ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && 0 != p_sys_queue->node[0].drop_wred_profile_id))
        {
            DsErmAqmQueueThrdProfile_m ds;

            sys_queue_drop_wred_profile_t sys_wred_profile_old;
            sal_memset(&sys_wred_profile_old, 0, sizeof(sys_wred_profile_old));
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->node[0].drop_wred_profile_id, cmd, &ds));
            sys_wred_profile_old.profile_id = p_sys_queue->node[0].drop_wred_profile_id;
            sys_wred_profile_old.lchip = lchip;
            sys_wred_profile_old.p_ds = &ds;

            CTC_ERROR_RETURN(ctc_spool_remove(p_usw_queue_master[lchip]->p_drop_wred_profile_pool, &sys_wred_profile_old, NULL));
            p_sys_queue->node[0].drop_wred_profile_id = DRV_FROM_TMM(lchip) ? 0 : MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM);
        }
    }
    else
    {
        if (MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM) != p_sys_queue->drop_wtd_profile_id)
        {
            DsErmQueueLimitedThrdProfile_m ds[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];

            sys_queue_drop_wtd_profile_t sys_wtd_profile_old;
            sal_memset(&sys_wtd_profile_old, 0, sizeof(sys_wtd_profile_old));
            sal_memset(&ds, 0, sizeof(ds));
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_sys_queue->drop_wtd_profile_id << 2, cmd, &ds));
            sys_wtd_profile_old.profile_id = p_sys_queue->drop_wtd_profile_id;
            sys_wtd_profile_old.lchip = lchip;
            sys_wtd_profile_old.p_ds = &ds;

            CTC_ERROR_RETURN(ctc_spool_remove(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool, &sys_wtd_profile_old, NULL));
            p_sys_queue->drop_wtd_profile_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM);
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_get_que_drop(uint8 lchip, sys_queue_node_t* p_sys_queue_node, ctc_qos_drop_array p_drop, uint16 queue_id, uint8 wred_mode)
{
    uint32 profile_id = 0;
    uint32 cmd = 0;
    uint8 level_num = 0;
    uint8 sc = 0;
    uint8 tc = 0;
    uint8 cng_level = 0;
    uint8 is_coexist = 0;
    uint32 index = 0;
    uint32 wred_profile = DRV_FROM_TMM(lchip) ? 0 : MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM);
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint32 is_dynamic = 0;
    uint8 temp_value = 0;
    uint8 wtd = 0;
    uint8 wred = 0;
    uint8 step = 0;
    DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile;
    ds_t erm_aqm_thrd_profile;
    DsErmAqmQueueCfg_m erm_aqm_queue_cfg;
    DsErmQueueCfg_m erm_queue_cfg;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_drop);

    sal_memset(&ds_que_thrd_profile, 0, sizeof(DsErmQueueLimitedThrdProfile_m));
    sal_memset(&erm_aqm_thrd_profile, 0, sizeof(erm_aqm_thrd_profile));
    sal_memset(&erm_aqm_queue_cfg, 0, sizeof(DsErmAqmQueueCfg_m));
    sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));

    sys_usw_queue_get_sc_tc(lchip, p_sys_queue_node, &sc, &tc);
    if (!SYS_IS_NETWORK_BASE_QUEUE(queue_id) && !SYS_IS_EXT_QUEUE(queue_id)&&wred_mode && (!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))))
    {
        return CTC_E_NOT_SUPPORT;
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        index = queue_id >> 2;
        cmd = DRV_IOR(DsErmAqmQueueThrdProfileId_t, DsErmAqmQueueThrdProfileId_g_0_aqmThrdProfileId_f + (queue_id&0x3));
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &wred_profile));
        wred = wred_profile;

        step = DsErmAqmQueueCfg_g_1_ewmaWeightFactor_f - DsErmAqmQueueCfg_g_0_ewmaWeightFactor_f;
        cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_queue_cfg));
        temp_value = GetDsErmAqmQueueCfg(V, g_0_ewmaWeightFactor_f + step * (queue_id & 0x3), &erm_aqm_queue_cfg);
    }
    else
    {
        if (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id))
        {
            index = (queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT))
            ? ((queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)) + MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC))
            : queue_id;
            cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_queue_cfg));
            wred_profile = GetDsErmAqmQueueCfg(V, queueThrdProfId_f , &erm_aqm_queue_cfg);
            temp_value = GetDsErmAqmQueueCfg(V, ewmaWeightFactor_f , &erm_aqm_queue_cfg);
        }
        wred = (wred_profile != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM));
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &profile_id));
        wtd = (profile_id != 0x3FFF);
    }
    else
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, queue_id , cmd, &erm_queue_cfg));
        profile_id = GetDsErmQueueCfg(V, queueLimitedThrdProfId_f , &erm_queue_cfg);
        wtd = (profile_id != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM));
    }

    if(wred && wtd)
    {
        is_coexist = 1;
    }
    cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedAutoEn_f);
    index = DRV_FROM_TMM(lchip) ? queue_id : (profile_id << 2);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &is_dynamic));
    p_drop[0].drop.is_dynamic = is_dynamic;
    if(wred_mode)
    {
        cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, wred_profile, cmd, &erm_aqm_thrd_profile));
        p_drop[cng_level].drop.max_th[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.max_th[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.max_th[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.max_th[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMaxLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.min_th[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.min_th[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.min_th[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.min_th[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMinLen_f, &erm_aqm_thrd_profile) * 8;
        p_drop[cng_level].drop.drop_prob[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f, &erm_aqm_thrd_profile);
        p_drop[cng_level].drop.drop_prob[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredProbFactor_f, &erm_aqm_thrd_profile);
        p_drop[cng_level].drop.drop_prob[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredProbFactor_f, &erm_aqm_thrd_profile);
        p_drop[cng_level].drop.drop_prob[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredProbFactor_f, &erm_aqm_thrd_profile);
        p_drop[cng_level].drop.is_coexist = is_coexist;
        p_drop[cng_level].drop.weight = temp_value;
    }
    else if(is_dynamic == 0)
    {
        level_num = p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num;
        if (level_num == 0)
        {
            return CTC_E_NONE;
        }
        for (cng_level = 0; cng_level < level_num; cng_level++)
        {
            temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cng_level + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-level_num)):0;
            index = DRV_FROM_TMM(lchip) ? queue_id : ((profile_id << 2) + temp_value);
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
            p_drop[cng_level].drop.max_th[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f, &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.max_th[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f, &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.max_th[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f, &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.max_th[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f, &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.ecn_th[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.ecn_th[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.ecn_th[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.ecn_th[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
            p_drop[cng_level].drop.is_coexist = is_coexist;
        }
        
    }
    else if(is_dynamic == 1)
    {
        index = DRV_FROM_TMM(lchip) ? queue_id : (profile_id << 2);
        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
        p_drop[cng_level].drop.drop_factor[0] = drop_factor[GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f, &ds_que_thrd_profile)];
        p_drop[cng_level].drop.drop_factor[1] = drop_factor[GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f, &ds_que_thrd_profile)];
        p_drop[cng_level].drop.drop_factor[2] = drop_factor[GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f, &ds_que_thrd_profile)];
        p_drop[cng_level].drop.drop_factor[3] = drop_factor[GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f, &ds_que_thrd_profile)];
        p_drop[cng_level].drop.ecn_th[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
        p_drop[cng_level].drop.ecn_th[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
        p_drop[cng_level].drop.ecn_th[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
        p_drop[cng_level].drop.ecn_th[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_que_thrd_profile) * 8;
        p_drop[cng_level].drop.is_coexist = is_coexist;
    }
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_queue_drop_add_static_profile(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    sys_queue_drop_wtd_profile_t sys_profile_new;
    sys_queue_guarantee_t sys_guarantee_new;
    DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile[CTC_RESRC_MAX_CONGEST_LEVEL_NUM];
    DsErmQueueGuaranteedThrdProfile_m ds_que_guaran_profile;
    uint16 index = 0;
    uint32 cmd = 0;
    uint16 profile_index = 0;
    uint32 field_val = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&sys_profile_new, 0, sizeof(sys_queue_drop_wtd_profile_t));
    sal_memset(&sys_guarantee_new, 0, sizeof(sys_queue_guarantee_t));
    sal_memset(&ds_que_guaran_profile, 0, sizeof(ds_que_guaran_profile));
    /* queue guarantee use 20 default*/
    SetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f, &ds_que_guaran_profile, 20);
    cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds_que_guaran_profile));
    sys_guarantee_new.lchip = lchip;
    sys_guarantee_new.p_ds = &ds_que_guaran_profile;
    CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_queue_guarantee_pool, &sys_guarantee_new));
    field_val = (DRV_IS_DUET2(lchip)) ? 0x7FF : 0xFFF;
    /* sc0 sc1 sc2 sc3 use the same factor*/
    if(p_usw_queue_master[lchip]->resrc_check_mode == 0)
    {
        sal_memset(ds_que_thrd_profile, 0, sizeof(ds_que_thrd_profile));

        cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        index = (profile_index << 2);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, ds_que_thrd_profile));
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f, &ds_que_thrd_profile, 0);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f, &ds_que_thrd_profile, 0);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f, &ds_que_thrd_profile, 0);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f, &ds_que_thrd_profile, 0);
        SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedAutoEn_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedAutoEn_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedAutoEn_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedAutoEn_f , &ds_que_thrd_profile, field_val);
        cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        index = (profile_index << 2);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, ds_que_thrd_profile));

        sys_profile_new.profile_id = profile_index;
        sys_profile_new.lchip = lchip;
        sys_profile_new.cng_num = 1;
        sys_profile_new.p_ds = ds_que_thrd_profile;

        CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool, &sys_profile_new));
        /* add 0 thrd static profile for change cpu sch*/
        profile_index = 1;
        sal_memset(ds_que_thrd_profile, 0, sizeof(ds_que_thrd_profile));
        SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
        cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
        index = profile_index << 2;
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, ds_que_thrd_profile));
        sys_profile_new.profile_id = profile_index;
        sys_profile_new.lchip = lchip;
        sys_profile_new.cng_num = 1;
        sys_profile_new.p_ds = ds_que_thrd_profile;
        CTC_ERROR_RETURN(ctc_spool_static_add(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool, &sys_profile_new));
    }

    return CTC_E_NONE;
}

int32
sys_usw_queue_set_drop_enable(uint8 lchip, uint8 wred_mode, ctc_qos_drop_array drop_array,
                                      sys_queue_node_t* p_sys_queue_node)
{
    int32 ret = 0;
    uint8 is_dynamic = 0;
    uint8 wred_weight = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_queue_node);
    is_dynamic = drop_array[0].drop.is_dynamic;
    wred_weight = drop_array[0].drop.weight;

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_resrc_set_que_drop && (!wred_mode))
    {
        return MCHIP_QOS(lchip)->qos_resrc_set_que_drop(lchip, is_dynamic, 1, drop_array, p_sys_queue_node);
    }

    /*add drop prof*/
    CTC_ERROR_GOTO(_sys_usw_queue_drop_add_profile(lchip, wred_mode, is_dynamic,drop_array,
                                                            p_sys_queue_node), ret, error0);

    /*write drop prof*/
    CTC_ERROR_GOTO(_sys_usw_queue_drop_write_profile_to_asic(lchip, wred_mode,is_dynamic,drop_array,
                                                                     p_sys_queue_node), ret, error1);

    /*write drop ctl and count*/
    CTC_ERROR_GOTO(_sys_usw_queue_drop_write_asic(lchip, wred_mode, wred_weight,
                                                           p_sys_queue_node), ret, error1);


    return ret;

error1:
    _sys_usw_queue_drop_remove_profile(lchip, wred_mode, p_sys_queue_node);
error0:
    return ret;

}

int32
sys_usw_queue_set_drop_disable(uint8 lchip, uint8 wred_mode, sys_queue_node_t* p_sys_queue_node)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_sys_queue_node);

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_resrc_set_que_drop && (!wred_mode))
    {
        ctc_qos_drop_array drop_array;
        sal_memset(&drop_array, 0, sizeof(drop_array));
        return MCHIP_QOS(lchip)->qos_resrc_set_que_drop(lchip, 0, 0, drop_array, p_sys_queue_node);
    }

    CTC_ERROR_RETURN(_sys_usw_queue_drop_clear_asic(lchip, wred_mode, p_sys_queue_node));

    CTC_ERROR_RETURN(_sys_usw_queue_drop_remove_profile(lchip, wred_mode, p_sys_queue_node));


    return CTC_E_NONE;
}


STATIC int32
_sys_usw_queue_set_queue_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint16 queue_id = 0;
    uint8  wred_mode = 0;
    ctc_qos_queue_drop_t *p_queue_drop = NULL;
    sys_queue_node_t* p_sys_queue_node = NULL;
    ctc_qos_drop_array drop_array;
    uint8 i = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_drop);
    p_queue_drop = &p_drop->drop;

    sal_memset(&drop_array, 0, sizeof(drop_array));

    /*get queue_id*/
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,
                                                       &p_drop->queue,
                                                       &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    if(p_queue_drop->ecn_mark_th != 0)
    {
        for (i = 0; i < CTC_DROP_PREC_NUM; i++)
        {
            p_queue_drop->ecn_th[i] = p_queue_drop->ecn_mark_th;
        }
    }
    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        CTC_MAX_VALUE_CHECK(p_queue_drop->min_th[i],    MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
        CTC_MAX_VALUE_CHECK(p_queue_drop->max_th[i],    MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
        CTC_MAX_VALUE_CHECK(p_queue_drop->min_th[i],    p_queue_drop->max_th[i] );
        CTC_MAX_VALUE_CHECK(p_queue_drop->drop_prob[i], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_PROB) );
        CTC_MAX_VALUE_CHECK(p_queue_drop->ecn_th[i],    MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
        CTC_MAX_VALUE_CHECK(p_queue_drop->drop_factor[i],SYS_MAX_DROP_FACTOR);
        if(0 == p_queue_drop->ecn_th[i])
        {
            p_queue_drop->ecn_th[i] = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) ;
        }
    }

    for (i = 0; i < CTC_RESRC_MAX_CONGEST_LEVEL_NUM; i ++)
    {
        sal_memcpy(&drop_array[i].drop, p_queue_drop, sizeof(ctc_qos_queue_drop_t));
    }
    CTC_MAX_VALUE_CHECK(p_queue_drop->weight, SYS_WRED_EWMA_MAX_WEIGHT);
    wred_mode = (p_queue_drop->mode == CTC_QUEUE_DROP_WRED);
    if(wred_mode && (!SYS_IS_NETWORK_BASE_QUEUE(queue_id) && !SYS_IS_EXT_QUEUE(queue_id)) && (!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(sys_usw_queue_set_drop_enable(lchip, wred_mode, drop_array, p_sys_queue_node));
    if (!p_queue_drop->is_coexist && (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id) || DRV_FROM_TMM(lchip)))
    {
        CTC_ERROR_RETURN(sys_usw_queue_set_drop_disable(lchip, !wred_mode, p_sys_queue_node));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_get_queue_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    uint16 queue_id = 0;
    uint8  wred_mode = 0;
    sys_queue_node_t* p_sys_queue_node = NULL;
    ctc_qos_drop_array drop_array;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_drop);

    sal_memset(&drop_array, 0, sizeof(drop_array));

    /*get queue_id*/
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,
                                                       &p_drop->queue,
                                                       &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    wred_mode = (p_drop->drop.mode == CTC_QUEUE_DROP_WRED);

    drop_array[0].drop.mode = p_drop->drop.mode;
    CTC_ERROR_RETURN(_sys_usw_queue_get_que_drop(lchip, p_sys_queue_node, drop_array, queue_id, wred_mode));
    sal_memcpy(&p_drop->drop, &drop_array[0].drop, sizeof(ctc_qos_queue_drop_t));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_set_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsErmPortLimitedThrdProfile_m ds_port_thrd_profile;
    uint32 cmd = 0;
    uint16 lport = 0;
    uint32 chan_id = 0;
    uint8  drop_factor[11] = {15,14,13,12,11,10,9,0,1,2,3};
    uint8  i = 0;
    uint8  step = 0;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);

    sal_memset(&ds_port_thrd_profile, 0, sizeof(DsErmPortLimitedThrdProfile_m));

    dmps_port_info.rx    = 0;
    dmps_port_info.gport = p_drop->gport;
    dmps_port_info.index = CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_COMMON_USELESS_CHANNEL)
    {
        return CTC_E_INVALID_PARAM;
    }
    if(p_drop->drop.mode != CTC_QUEUE_DROP_WTD)
    {
        return CTC_E_NOT_SUPPORT;
    }
    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        CTC_MAX_VALUE_CHECK(p_drop->drop.max_th[i],    MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE) );
        CTC_MAX_VALUE_CHECK(p_drop->drop.drop_factor[i],SYS_MAX_DROP_FACTOR);
    }

    /*wtd*/
    step = DsErmPortLimitedThrdProfile_g_1_portLimitedAutoEn_f - DsErmPortLimitedThrdProfile_g_0_portLimitedAutoEn_f;
    cmd = DRV_IOR(DsErmPortLimitedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds_port_thrd_profile));
    for (i = 0; i < CTC_DROP_PREC_NUM; i++)
    {
        SetDsErmPortLimitedThrdProfile(V, g_0_portLimitedThrd_f + step * i, &ds_port_thrd_profile, p_drop->drop.is_dynamic ?  0 : p_drop->drop.max_th[i] / 8);
        SetDsErmPortLimitedThrdProfile(V, g_0_portLimitedFactor_f + step * i, &ds_port_thrd_profile, drop_factor[p_drop->drop.drop_factor[i]]);
        SetDsErmPortLimitedThrdProfile(V, g_0_portLimitedAutoEn_f + step * i, &ds_port_thrd_profile, p_drop->drop.is_dynamic ? 1 : 0);
    }
    cmd = DRV_IOW(DsErmPortLimitedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds_port_thrd_profile));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_get_port_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsErmPortLimitedThrdProfile_m ds_port_thrd_profile;
    uint32 cmd = 0;
    uint16 lport = 0;
    uint32 chan_id = 0;
    uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
    uint8  i = 0;
    uint8  step = 0;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_drop->gport, lchip, lport);

    sal_memset(&ds_port_thrd_profile, 0, sizeof(DsErmPortLimitedThrdProfile_m));

    dmps_port_info.rx    = 0;
    dmps_port_info.gport = p_drop->gport;
    dmps_port_info.index = CTC_MAP_GPORT_TO_MCHAN_IDX(p_drop->gport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_COMMON_USELESS_CHANNEL)
    {
        return CTC_E_INVALID_PARAM;
    }
    if(p_drop->drop.mode != CTC_QUEUE_DROP_WTD)
    {
        return CTC_E_NOT_SUPPORT;
    }
    /*wtd*/
    step = DsErmPortLimitedThrdProfile_g_1_portLimitedAutoEn_f - DsErmPortLimitedThrdProfile_g_0_portLimitedAutoEn_f;
    cmd = DRV_IOR(DsErmPortLimitedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds_port_thrd_profile));
    p_drop->drop.is_dynamic = GetDsErmPortLimitedThrdProfile(V, g_0_portLimitedAutoEn_f, &ds_port_thrd_profile);
    if (p_drop->drop.is_dynamic == 1)
    {   
        p_drop->drop.drop_factor[0] = drop_factor[GetDsErmPortLimitedThrdProfile(V, g_0_portLimitedFactor_f + step * i, &ds_port_thrd_profile)];
        p_drop->drop.drop_factor[1] = drop_factor[GetDsErmPortLimitedThrdProfile(V, g_1_portLimitedFactor_f + step * i, &ds_port_thrd_profile)];
        p_drop->drop.drop_factor[2] = drop_factor[GetDsErmPortLimitedThrdProfile(V, g_2_portLimitedFactor_f + step * i, &ds_port_thrd_profile)];
        p_drop->drop.drop_factor[3] = drop_factor[GetDsErmPortLimitedThrdProfile(V, g_3_portLimitedFactor_f + step * i, &ds_port_thrd_profile)];
    }
    else
    {
        p_drop->drop.max_th[0] = GetDsErmPortLimitedThrdProfile(V, g_0_portLimitedThrd_f + step * i, &ds_port_thrd_profile) * 8;
        p_drop->drop.max_th[1] = GetDsErmPortLimitedThrdProfile(V, g_1_portLimitedThrd_f + step * i, &ds_port_thrd_profile) * 8;
        p_drop->drop.max_th[2] = GetDsErmPortLimitedThrdProfile(V, g_2_portLimitedThrd_f + step * i, &ds_port_thrd_profile) * 8;
        p_drop->drop.max_th[3] = GetDsErmPortLimitedThrdProfile(V, g_3_portLimitedThrd_f + step * i, &ds_port_thrd_profile) * 8;
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_set_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    CTC_PTR_VALID_CHECK(p_drop);
    switch(p_drop->type)
    {
    case CTC_QOS_BUFFER_NONE:
    case CTC_QOS_BUFFER_QUEUE:
        return _sys_usw_queue_set_queue_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT:
        return _sys_usw_queue_set_port_drop(lchip, p_drop);
    default:
        return  CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}
int32
sys_usw_queue_get_drop(uint8 lchip, ctc_qos_drop_t* p_drop)
{
    CTC_PTR_VALID_CHECK(p_drop);
    switch(p_drop->type)
    {
    case CTC_QOS_BUFFER_NONE:
    case CTC_QOS_BUFFER_QUEUE:
        return _sys_usw_queue_get_queue_drop(lchip, p_drop);
    case CTC_QOS_BUFFER_PORT:
        return _sys_usw_queue_get_port_drop(lchip, p_drop);
    default:
        return  CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_set_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t queue_min)
{
    uint32 cmd                     = 0;
    uint32 field_value             = 0;
    uint16 queue_id                 = 0;
    sys_queue_node_t* p_sys_queue_node = NULL;

    CTC_MAX_VALUE_CHECK(queue_min.threshold, DRV_FROM_TMM(lchip) ? 0x3ff : 0x7fff);
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &queue_min.queue, &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        field_value = queue_min.threshold;
        cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DsErmQueueGuaranteedThrdProfile_queueGuaranteedThrd_f);
        DRV_FIELD_IOCTL(lchip, queue_id, cmd, &field_value);
    }
    else
    {
        sys_queue_guarantee_t sys_profile_old;
        sys_queue_guarantee_t sys_profile_new;
        sys_queue_guarantee_t* p_sys_profile_get = NULL;
        DsErmQueueGuaranteedThrdProfile_m ds_old;
        DsErmQueueGuaranteedThrdProfile_m ds_new;
        sal_memset(&sys_profile_new, 0, sizeof(sys_profile_new));
        sal_memset(&sys_profile_old, 0, sizeof(sys_profile_old));
        sal_memset(&ds_old, 0, sizeof(ds_old));
        sal_memset(&ds_new, 0, sizeof(ds_new));
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_queueGuaranteedThrdProfId_f);
        DRV_FIELD_IOCTL(lchip, queue_id, cmd, &field_value);

        cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, field_value, cmd, &ds_old);
        sys_profile_old.profile_id = field_value;
        sys_profile_old.lchip = lchip;
        sys_profile_old.p_ds = &ds_old;

        SetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f , &ds_new, queue_min.threshold);
        sys_profile_new.lchip = lchip;
        sys_profile_new.p_ds = &ds_new;
        
        CTC_ERROR_RETURN(_sys_usw_qos_guarantee_profile_add_spool(lchip, &sys_profile_old, &sys_profile_new, &p_sys_profile_get));

        cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, p_sys_profile_get->profile_id, cmd, sys_profile_new.p_ds);

        field_value = p_sys_profile_get->profile_id;
        cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_queueGuaranteedThrdProfId_f);
        DRV_FIELD_IOCTL(lchip, queue_id, cmd, &field_value);
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_get_queue_min(uint8 lchip, ctc_qos_resrc_queue_min_t* queue_min)
{
    uint32 cmd                      = 0;
    uint32 field_value              = 0;
    uint32 index                    = 0;
    uint16 queue_id                 = 0;
    sys_queue_node_t* p_sys_queue_node = NULL;

    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &queue_min->queue, &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        index = queue_id;
    }
    else
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_queueGuaranteedThrdProfId_f);
        DRV_FIELD_IOCTL(lchip, queue_id, cmd, &index);
    }
 
    cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DsErmQueueGuaranteedThrdProfile_queueGuaranteedThrd_f);
    DRV_FIELD_IOCTL(lchip, index, cmd, &field_value);
    queue_min->threshold = field_value;

    return CTC_E_NONE;
}

int32
_sys_usw_queue_alloc_port_min_profile(uint8 lchip, uint16 index, uint8 dir, uint16 thrd, uint8 *profile_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 entry_num = 0;
    uint32 tbl_id1[CTC_BOTH_DIRECTION] = {DsIrmPortCfg_t, DsErmPortCfg_t};
    uint32 tbl_id2[CTC_BOTH_DIRECTION] = {DsIrmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_t};
    uint8 bimmap = 0;
    uint8 loop = 0;
    DsIrmPortCfg_m port_cfg;
    DsIrmPortGuaranteedThrdProfile_m port_prof;

    /*1.thrd = 0 mean disbale, use profile id 7*/
    if(thrd == 0)
    {
        *profile_id = SYS_PORT_GUARANTEE_PROF_NUM - 1;
        return CTC_E_NONE;
    }

    /*2.get profile ref_cnf base on port*/
    cmd = DRV_IOR(tbl_id1[dir], DRV_ENTRY_FLAG);
    sys_usw_ftm_query_table_entry_num(lchip, tbl_id1[dir], &entry_num);
    for (loop = 0; loop < entry_num; loop++)
    {
        if(loop == index)
        {
            continue;
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, cmd, &port_cfg));
        field_value = GetDsIrmPortCfg(V, portGuaranteedThrdProfId_f, &port_cfg);
        CTC_BIT_SET(bimmap, field_value);
    }

    /*3.compare thrd, if find, share profile id*/
    cmd = DRV_IOR(tbl_id2[dir], DRV_ENTRY_FLAG);
    for(loop = 0; loop < SYS_PORT_GUARANTEE_PROF_NUM - 1; loop++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, cmd, &port_prof));
        field_value = GetDsIrmPortGuaranteedThrdProfile(V, portGuaranteedThrd_f, &port_prof);
        if(field_value == thrd && CTC_IS_BIT_SET(bimmap, loop))
        {
            *profile_id = loop;
            return CTC_E_NONE;
        }
    }

    /*4. if not find, alloc new profile id*/
    for(loop = 0; loop < SYS_PORT_GUARANTEE_PROF_NUM - 1; loop++)
    {
        if(!CTC_IS_BIT_SET(bimmap, loop))
        {
            *profile_id = loop;
            return CTC_E_NONE;
        }
    }
    return CTC_E_NO_RESOURCE;
}

int32
_sys_usw_queue_get_port_min_index(uint8 lchip, uint8 dir, uint16 lport, uint16 chan_id, uint16 *port_index, uint8 *is_porttc)
{
    uint32 cmd                     = 0;
    uint32 local_phy_port_en       = 0;
    uint32 local_phy_port_pri_en   = 0;
    uint32 local_phy_port_base     = 0;
    uint32 local_phy_port_en_chan  = 0;
    ds_t ds;

    if(dir == CTC_EGRESS)
    {
        return CTC_E_NONE;
    }
    cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    local_phy_port_en = GetIrmMiscCtl(V, localPhyPortResrcEn_f, &ds);
    local_phy_port_pri_en = GetIrmMiscCtl(V, localPhyPortResrcPriEn_f, &ds);
    local_phy_port_base = GetIrmMiscCtl(V, localPhyPortResrcBase_f, &ds);
    cmd = DRV_IOR(DsIrmChannel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &ds));
    local_phy_port_en_chan = GetDsIrmChannel(V, localPhyPortResrcEn_f, &ds);

    if (DRV_FROM_TMM(lchip))
    {
        *port_index = (local_phy_port_en && local_phy_port_en_chan) ? lport : chan_id;
    }
    else
    {
        if(local_phy_port_en && local_phy_port_en_chan && local_phy_port_pri_en && lport - local_phy_port_base < SYS_MAX_OOBFC_INGRESS_PRI_PORT_NUM)
        {
            *port_index = lport - local_phy_port_base + SYS_MAX_OOBFC_PORT_CFG_BASE;  /*[64,64+32)*/
        }
        else if(local_phy_port_en && local_phy_port_en_chan && !local_phy_port_pri_en)
        {
            *port_index = lport + MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM) * SYS_PRIO_CLASS_NUM; /*use prottc,[512,512+32*8)*/
            *is_porttc = 1;
        }
        else if(chan_id >= MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM))
        {
            *port_index = (chan_id & 0x1F) + SYS_MAX_OOBFC_PORT_CFG_BASE + SYS_MAX_OOBFC_INGRESS_PRI_PORT_NUM; /*[96,96+20)*/
        }
        else
        {
            *port_index = chan_id; /*[0,64)*/
        }
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_set_port_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min)
{
    uint8  profile_id              = 0;
    uint8  is_porttc               = 0; 
    uint16 lport                   = 0;
    uint16 port_index              = 0;
    uint16 index                   = 0;
    uint32 cmd                     = 0;
    uint32 field_value             = 0;
    uint32 chan_id                 = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(port_min->gport, lchip, lport);
    dmps_port_info.gport = port_min->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_COMMON_USELESS_CHANNEL)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(_sys_usw_queue_get_port_min_index(lchip, port_min->dir, lport, chan_id, &port_index, &is_porttc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " port_index = %d, is_porttc = %d\n", port_index, is_porttc);

    if(port_min->prio_class_en)
    {
        CTC_MAX_VALUE_CHECK(port_min->prio_class, 7);
        CTC_MAX_VALUE_CHECK(port_min->dir, CTC_INGRESS);
        index = port_index << 3 | port_min->prio_class;
        cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        SetDsIrmPortTcGuaranteedThrdProfile(V, portTcGuaranteedThrd_f, &ds, port_min->threshold);
        cmd = DRV_IOW(DsIrmPortTcGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));

        return CTC_E_NONE;
    }

    /* write profile to asic */
    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if(!DRV_FROM_TMM(lchip))
        {
            CTC_ERROR_RETURN(_sys_usw_queue_alloc_port_min_profile(lchip, port_index, CTC_INGRESS, port_min->threshold, &profile_id));
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " profile id = %d, threshold = %d\n", profile_id, port_min->threshold);
        }
        field_value = port_min->threshold;
        index = DRV_FROM_TMM(lchip) ? port_index : profile_id;
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfile_t, DsIrmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
        index = port_index;
        field_value = profile_id;
        cmd = is_porttc ? DRV_IOW(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g2_portGuaranteedThrdProfId_f)
                        : DRV_IOW(DsIrmPortCfg_t, DsIrmPortCfg_portGuaranteedThrdProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if(!DRV_FROM_TMM(lchip))
        {
            CTC_ERROR_RETURN(_sys_usw_queue_alloc_port_min_profile(lchip, chan_id, CTC_EGRESS, port_min->threshold, &profile_id));
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " profile id = %d, threshold = %d\n", profile_id, port_min->threshold);
        }
        field_value = port_min->threshold;
        index = DRV_FROM_TMM(lchip) ? chan_id : profile_id;
        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
        index = chan_id;
        field_value = profile_id;
        cmd = DRV_IOW(DsErmPortCfg_t, DsErmPortCfg_portGuaranteedThrdProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
    }

    return CTC_E_NONE;
}
int32
sys_usw_queue_get_port_min(uint8 lchip, ctc_qos_resrc_port_min_t *port_min)
{
    uint8  is_porttc               = 0; 
    uint16 lport                   = 0;
    uint32 cmd                     = 0;
    uint32 field_value             = 0;
    uint32 chan_id                 = 0;
    uint16 index                   = 0;
    uint16 port_index              = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(port_min->gport, lchip, lport);
    dmps_port_info.gport = port_min->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (chan_id == SYS_COMMON_USELESS_CHANNEL)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(_sys_usw_queue_get_port_min_index(lchip, port_min->dir, lport, chan_id, &port_index, &is_porttc));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, " port_index = %d, is_porttc = %d\n", port_index, is_porttc);

    if(port_min->prio_class_en)
    {
        CTC_MAX_VALUE_CHECK(port_min->prio_class, 7);
        CTC_MAX_VALUE_CHECK(port_min->dir, CTC_INGRESS);
        index = port_index << 3 | port_min->prio_class;
        cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        port_min->threshold = GetDsIrmPortTcGuaranteedThrdProfile(V, portTcGuaranteedThrd_f, &ds);
        return CTC_E_NONE;
    }

    /* write profile to asic */
    if ((CTC_INGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if(!DRV_FROM_TMM(lchip))
        {
            cmd = is_porttc ? DRV_IOR(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g2_portGuaranteedThrdProfId_f)
                            : DRV_IOR(DsIrmPortCfg_t, DsIrmPortCfg_portGuaranteedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, port_index, cmd, &field_value));
            index = field_value;
        }
        else
        {
            index = port_index;
        }
        cmd = DRV_IOR(DsIrmPortGuaranteedThrdProfile_t, DsIrmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
        port_min->threshold = field_value;
    }

    if ((CTC_EGRESS == port_min->dir) || (CTC_BOTH_DIRECTION == port_min->dir))
    {
        if(!DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(DsErmPortCfg_t, DsErmPortCfg_portGuaranteedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_value));
            index = field_value;
        }
        else
        {
            index = chan_id;
        }
        cmd = DRV_IOR(DsErmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
        port_min->threshold= field_value;
    }

    return CTC_E_NONE;
}


int32
sys_usw_qos_set_resrc_classify_pool(uint8 lchip, ctc_qos_resrc_classify_pool_t *p_pool)
{
    uint16 index                    = 0;
    uint32 cmd                      = 0;
    uint32 field_value              = 0;
    uint32 chan_id                  = 0;
    uint16 lport                    = 0;
    uint8  dp                       = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsIrmPrioScTcMap_m irm_pri_to_sc_tc_map;
    DsErmPrioScTcMap_m erm_prio_sc_tc_map;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_pool->gport, lchip, lport);
    CTC_MAX_VALUE_CHECK(p_pool->pool, 3);
    CTC_MAX_VALUE_CHECK(p_pool->priority, 15);
    dmps_port_info.gport = p_pool->gport;

    if (p_pool->dir == CTC_INGRESS)
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        sal_memset(&irm_pri_to_sc_tc_map, 0, sizeof(DsIrmPrioScTcMap_m));
        if (p_pool->pool == CTC_QOS_IGS_RESRC_NON_DROP_POOL)
        {
            for (dp = 0; dp < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp++)
            {
                index = dp << 5 | p_pool->priority;
                cmd = DRV_IOR(DsIrmPrioScTcMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_pri_to_sc_tc_map));
                SetDsIrmPrioScTcMap(V, g1_1_mappedSc_f , &irm_pri_to_sc_tc_map, p_pool->pool);
                cmd = DRV_IOW(DsIrmPrioScTcMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_pri_to_sc_tc_map));
            }
            field_value = SYS_ERM_PROFILE_USER_DEFINE;
        }
        else
        {
            field_value = SYS_ERM_PROFILE_DEFAULT;
        }

        /* all port are mapping profile 0 */
        index = chan_id;
        cmd = DRV_IOW(DsIrmChannel_t, DsIrmChannel_irmProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
    }
    else if (p_pool->dir == CTC_EGRESS)
    {
        if (p_usw_queue_master[lchip]->egs_pool[p_pool->pool].egs_congest_level_num == 0 && !DRV_FROM_AT(lchip))   /* the sc is not exist */
        {
            return CTC_E_INVALID_PARAM;
        }

        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        sal_memset(&erm_prio_sc_tc_map, 0, sizeof(DsErmPrioScTcMap_m));
        if(p_usw_queue_master[lchip]->group_id_ets[chan_id].group_id != INVALID_QUEUE_GROUP_ID_ETS)
        {
            index = p_pool->priority;
            cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
            SetDsErmPrioScTcMap(V, g1_5_mappedSc_f, &erm_prio_sc_tc_map, p_pool->pool == CTC_QOS_EGS_RESRC_NON_DROP_POOL ? p_pool->pool : 0);
            cmd = DRV_IOW(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
                        
            return CTC_E_NONE;
        }

        if (p_pool->pool == CTC_QOS_EGS_RESRC_NON_DROP_POOL)
        {
            index = p_pool->priority;
            cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
            SetDsErmPrioScTcMap(V, g1_1_mappedSc_f , &erm_prio_sc_tc_map, p_pool->pool);
            cmd = DRV_IOW(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));

            field_value = SYS_ERM_PROFILE_USER_DEFINE;
        }
        else
        {
            field_value = SYS_ERM_PROFILE_DEFAULT;
        }

        /* default use profile 0, sc use profile 1 */
        index = chan_id;
        cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_get_resrc_classify_pool(uint8 lchip, ctc_qos_resrc_classify_pool_t *p_pool)
{
    uint16 index                    = 0;
    uint32 cmd                      = 0;
    uint32 field_value              = 0;
    uint32 chan_id                  = 0;
    uint16 lport                    = 0;
    uint8  step                     = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsIrmPrioScTcMap_m irm_pri_to_sc_tc_map;
    DsErmPrioScTcMap_m erm_prio_sc_tc_map;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_pool->gport, lchip, lport);
    CTC_MAX_VALUE_CHECK(p_pool->pool, 3);
    CTC_MAX_VALUE_CHECK(p_pool->priority, 15);
    dmps_port_info.gport = p_pool->gport;

    if (p_pool->dir == CTC_INGRESS)
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        /* all port are mapping profile 0 */
        index = chan_id;
        cmd = DRV_IOR(DsIrmChannel_t, DsIrmChannel_irmProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));

        sal_memset(&irm_pri_to_sc_tc_map, 0, sizeof(DsIrmPrioScTcMap_m));
        step = DsIrmPrioScTcMap_g1_1_mappedSc_f - DsIrmPrioScTcMap_g1_0_mappedSc_f;
        cmd = DRV_IOR(DsIrmPrioScTcMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_pool->priority, cmd, &irm_pri_to_sc_tc_map));
        p_pool->pool = GetDsIrmPrioScTcMap(V, g1_0_mappedSc_f + step * field_value, &irm_pri_to_sc_tc_map);
    }
    else if (p_pool->dir == CTC_EGRESS)
    {
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        CTC_MAX_VALUE_CHECK(chan_id, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1);

        /* default use profile 0, sc use profile 1 */
        index = chan_id;
        cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_ermProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));

        sal_memset(&erm_prio_sc_tc_map, 0, sizeof(DsErmPrioScTcMap_m));
        step = DsErmPrioScTcMap_g1_1_mappedSc_f - DsErmPrioScTcMap_g1_0_mappedSc_f;
        cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_pool->priority, cmd, &erm_prio_sc_tc_map));
        p_pool->pool = GetDsErmPrioScTcMap(V, g1_0_mappedSc_f + step * field_value, &erm_prio_sc_tc_map);
        if (p_usw_queue_master[lchip]->egs_pool[p_pool->pool].egs_congest_level_num == 0)   /* the sc is not exist */
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_set_resrc_queue_drop(uint8 lchip, ctc_qos_drop_array p_drop)
{
    uint8  tc                       = 0;
    uint16 index                    = 0;
    uint16 queue_id                 = 0;
    uint8 wred_mode = 0;
    sys_queue_node_t* p_sys_queue_node = NULL;

    if(p_usw_queue_master[lchip]->resrc_check_mode == 0)
    {
        return CTC_E_NOT_SUPPORT;
    }

    /* check para */
    for (index = 0; index < CTC_RESRC_MAX_CONGEST_LEVEL_NUM; index++)
    {
        if(p_drop[index].drop.ecn_mark_th != 0)
        {
            for (tc = 0; tc < 4; tc++)
            {
                p_drop[index].drop.ecn_th[tc] = p_drop[index].drop.ecn_mark_th;
            }
        }
        for (tc = 0; tc < 4; tc++)
        {
            CTC_MAX_VALUE_CHECK(p_drop[index].drop.min_th[tc], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
            CTC_MAX_VALUE_CHECK(p_drop[index].drop.max_th[tc], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
            CTC_MAX_VALUE_CHECK(p_drop[index].drop.drop_prob[tc], MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_PROB) );
            CTC_MAX_VALUE_CHECK(p_drop[index].drop.ecn_th[tc],MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) );
            CTC_MAX_VALUE_CHECK(p_drop[index].drop.drop_factor[tc],SYS_MAX_DROP_FACTOR);
            if(0 == p_drop[index].drop.ecn_th[tc])
            {
                p_drop[index].drop.ecn_th[tc] = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD) ;
            }
        }

    }

    /* get queue_id */
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip, &(p_drop[0].queue), &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    wred_mode = (p_drop[0].drop.mode == CTC_QUEUE_DROP_WRED);
    CTC_ERROR_RETURN(sys_usw_queue_set_drop_enable(lchip, wred_mode, p_drop, p_sys_queue_node));
    if (!p_drop[0].drop.is_coexist && (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id)))
    {
        CTC_ERROR_RETURN(sys_usw_queue_set_drop_disable(lchip, !wred_mode, p_sys_queue_node));
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_get_resrc_queue_drop(uint8 lchip, ctc_qos_drop_array p_drop)
{
    uint16 queue_id = 0;
    uint8  wred_mode = 0;
    sys_queue_node_t* p_sys_queue_node = NULL;

    if(p_usw_queue_master[lchip]->resrc_check_mode == 0)
    {
        return CTC_E_NOT_SUPPORT;
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_drop);

    /*get queue_id*/
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,
                                                       &p_drop[0].queue,
                                                       &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    wred_mode = (p_drop[0].drop.mode == CTC_QUEUE_DROP_WRED);
    CTC_ERROR_RETURN(_sys_usw_queue_get_que_drop(lchip, p_sys_queue_node, p_drop, queue_id, wred_mode));

    return CTC_E_NONE;
}

int32
sys_usw_queue_set_obm_pool(uint8 lchip, ctc_qos_obm_resrc_pool_t obm_resrc_pool)
{
    uint32 cmd = 0;
    uint8 loop = 0;
    uint8 idx1 = 0;
    uint8 idx2 = 0;
    uint8 dp_id = 0;
    NetRxBufManagement_m netrx_buf;

    CTC_MAX_VALUE_CHECK(obm_resrc_pool.index, SYS_PP_NUM(lchip)*MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP)*MCHIP_CAP(SYS_CAP_DP_MAX_NUM) - 1);
    for(loop = 0; loop < CTC_QOS_OBM_RESRC_POOL_MAX; loop++)
    {
        if(obm_resrc_pool.pool_thrd[loop] > MCHIP_CAP(SYS_CAP_QOS_DROP_OBM_TOTAL_POOL_SIZE))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if(!( obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY0] <= obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY1]
       && obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY1] < obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS0]
       && obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS0] <= obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS1]))
    {
        return CTC_E_INVALID_PARAM;
    }
    if (!(obm_resrc_pool.xon_thrd && obm_resrc_pool.xoff_thrd && obm_resrc_pool.xon_thrd < obm_resrc_pool.xoff_thrd 
          && obm_resrc_pool.xoff_thrd < MCHIP_CAP(SYS_CAP_QOS_DROP_OBM_TOTAL_POOL_SIZE)) 
        && (obm_resrc_pool.xon_thrd || obm_resrc_pool.xoff_thrd))
    {
        return CTC_E_INVALID_PARAM;
    }
    idx1 = obm_resrc_pool.index / MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP);
    idx2 = obm_resrc_pool.index % MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP);
    if (DRV_FROM_AT(lchip))
    {
        lchip = SYS_PP_BASE(lchip) + idx1 / MCHIP_CAP(SYS_CAP_DP_MAX_NUM);
        dp_id = idx1 % MCHIP_CAP(SYS_CAP_DP_MAX_NUM);
        idx1 = 0;
    }

    cmd = DRV_IOR(NetRxBufManagement_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_DP_EN(cmd, dp_id), &netrx_buf));
    if(obm_resrc_pool.xon_thrd || obm_resrc_pool.xoff_thrd)
    {
        SetNetRxBufManagement(V, cfgPauseXonThrd0_f +  idx2, &netrx_buf, obm_resrc_pool.xon_thrd);
        SetNetRxBufManagement(V, cfgPauseXoffThrd0_f + idx2, &netrx_buf, obm_resrc_pool.xoff_thrd);
    }
    SetNetRxBufManagement(V, cfgLowThrd0_f + idx2, &netrx_buf, obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY0]);
    SetNetRxBufManagement(V, cfgMidThrd0_f + idx2, &netrx_buf, obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY1]);
    SetNetRxBufManagement(V, cfgHighThrd0_f + idx2, &netrx_buf, obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS0]);
    SetNetRxBufManagement(V, cfgCriticalThrd0_f + idx2, &netrx_buf, obm_resrc_pool.pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS1]);
    cmd = DRV_IOW(NetRxBufManagement_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_DP_EN(cmd, dp_id), &netrx_buf));

    return CTC_E_NONE;
}

int32
sys_usw_queue_get_obm_pool(uint8 lchip, ctc_qos_obm_resrc_pool_t* obm_resrc_pool)
{
    uint32 cmd = 0;
    uint8 idx1 = 0;
    uint8 idx2 = 0;
    uint8 dp_id = 0;
    NetRxBufManagement_m netrx_buf;

    CTC_MAX_VALUE_CHECK(obm_resrc_pool->index, SYS_PP_NUM(lchip)*MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP)*MCHIP_CAP(SYS_CAP_DP_MAX_NUM) - 1);

    idx1 = obm_resrc_pool->index / MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP);
    idx2 = obm_resrc_pool->index % MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP);

    if (DRV_FROM_AT(lchip))
    {
        lchip = SYS_PP_BASE(lchip) + idx1 / MCHIP_CAP(SYS_CAP_DP_MAX_NUM);
        dp_id = idx1 % MCHIP_CAP(SYS_CAP_DP_MAX_NUM);
        idx1 = 0;
    }
    cmd = DRV_IOR(NetRxBufManagement_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, DRV_CMD_DP_EN(cmd, dp_id), &netrx_buf));
    
    obm_resrc_pool->xon_thrd  = GetNetRxBufManagement(V, cfgPauseXonThrd0_f + idx2, &netrx_buf);
    obm_resrc_pool->xoff_thrd = GetNetRxBufManagement(V, cfgPauseXoffThrd0_f + idx2, &netrx_buf);
    obm_resrc_pool->pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY0] = GetNetRxBufManagement(V, cfgLowThrd0_f + idx2, &netrx_buf);
    obm_resrc_pool->pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSY1] = GetNetRxBufManagement(V, cfgMidThrd0_f + idx2, &netrx_buf);
    obm_resrc_pool->pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS0] = GetNetRxBufManagement(V, cfgHighThrd0_f + idx2, &netrx_buf);
    obm_resrc_pool->pool_thrd[CTC_QOS_OBM_RESRC_POOL_LOSSLESS1] = GetNetRxBufManagement(V, cfgCriticalThrd0_f + idx2, &netrx_buf);

    return CTC_E_NONE;
}


int32
sys_usw_queue_set_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_resrc);

    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_POOL_CLASSIFY:
        CTC_ERROR_RETURN(sys_usw_qos_set_resrc_classify_pool(lchip, &p_resrc->u.pool));
        break;

    case CTC_QOS_RESRC_CFG_PORT_MIN:
        CTC_MAX_VALUE_CHECK(p_resrc->u.port_min.threshold, 255);
        CTC_ERROR_RETURN(sys_usw_queue_set_port_min(lchip, &p_resrc->u.port_min));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_DROP:
        CTC_ERROR_RETURN(sys_usw_qos_set_resrc_queue_drop(lchip, p_resrc->u.queue_drop));
        break;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        CTC_ERROR_RETURN(sys_usw_qos_fc_add_profile(lchip, &p_resrc->u.flow_ctl));
        break;

    case CTC_QOS_RESRC_CFG_FCDL_DETECT:
        CTC_ERROR_RETURN(sys_usw_qos_set_fcdl_detect(lchip, &p_resrc->u.fcdl_detect));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_MIN:
        CTC_ERROR_RETURN(sys_usw_queue_set_queue_min(lchip, p_resrc->u.queue_min));
        break;
    case CTC_QOS_RESRC_CFG_OBM_POOL:
        CTC_ERROR_RETURN(sys_usw_queue_set_obm_pool(lchip, p_resrc->u.obm_pool));
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_queue_get_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_resrc);

    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_POOL_CLASSIFY:
        CTC_ERROR_RETURN(sys_usw_qos_get_resrc_classify_pool(lchip, &p_resrc->u.pool));
        break;

    case CTC_QOS_RESRC_CFG_PORT_MIN:
        CTC_ERROR_RETURN(sys_usw_queue_get_port_min(lchip, &p_resrc->u.port_min));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_DROP:
        CTC_ERROR_RETURN(sys_usw_qos_get_resrc_queue_drop(lchip, p_resrc->u.queue_drop));
        break;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        CTC_ERROR_RETURN(sys_usw_qos_fc_get_profile(lchip, &p_resrc->u.flow_ctl));
        break;

    case CTC_QOS_RESRC_CFG_FCDL_DETECT:
        CTC_ERROR_RETURN(sys_usw_qos_get_fcdl_detect(lchip, &p_resrc->u.fcdl_detect));
        break;

    case CTC_QOS_RESRC_CFG_QUEUE_MIN:
        CTC_ERROR_RETURN(sys_usw_queue_get_queue_min(lchip, &p_resrc->u.queue_min));
        break;
    case CTC_QOS_RESRC_CFG_OBM_POOL:
        CTC_ERROR_RETURN(sys_usw_queue_get_obm_pool(lchip, &p_resrc->u.obm_pool));
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_queue_query_pool_stats(uint8 lchip, ctc_qos_resrc_pool_stats_t* p_stats)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint16 queue_id = 0;
    uint32 chan_id = 0;
    uint16 lport = 0;
    uint32 snapshot_en = 0;
    ctc_qos_queue_id_t queue;
    ctc_qos_queue_id_t queue_temp;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    CTC_PTR_VALID_CHECK(p_stats);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&queue, 0, sizeof(queue));

    cmd = DRV_IOR(IrmMiscCtl_t, IrmMiscCtl_c2cCntLockEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &snapshot_en));
    dmps_port_info.gport = p_stats->gport;

    switch (p_stats->type)
    {
    case CTC_QOS_RESRC_STATS_IGS_POOL_COUNT:
        if(snapshot_en)
        {
            if (CTC_QOS_IGS_RESRC_C2C_POOL == p_stats->pool)
            {
                cmd = DRV_IOR(DsIrmMiscCnt_t, DsIrmMiscCnt_c2cShadowCnt_f + p_stats->pool);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            }
            else if (CTC_QOS_IGS_RESRC_CONTROL_POOL == p_stats->pool)
            {
                cmd = DRV_IOR(DsIrmMiscCnt_t, DsIrmMiscCnt_criticalShadowCnt_f + p_stats->pool);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            }
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_stats->pool, CTC_QOS_IGS_RESRC_SPAN_POOL);
            cmd = DRV_IOR(DsIrmScCnt_t, DsIrmScCnt_g_0_scCnt_f + p_stats->pool);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        }
        p_stats->count = field_value;

        break;

    case CTC_QOS_RESRC_STATS_IGS_TOTAL_COUNT:
        cmd = DRV_IOR(DsIrmMiscCnt_t, DsIrmMiscCnt_totalCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        p_stats->count = field_value;

        break;

    case CTC_QOS_RESRC_STATS_EGS_POOL_COUNT:
        CTC_MAX_VALUE_CHECK(p_stats->pool, CTC_QOS_EGS_RESRC_CONTROL_POOL);
        cmd = DRV_IOR(DsErmScCnt_t, DsErmScCnt_g_0_scCnt_f + p_stats->pool);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        p_stats->count = field_value;
        break;

    case CTC_QOS_RESRC_STATS_EGS_TOTAL_COUNT:
        cmd = DRV_IOR(DsErmMiscCnt_t, DsErmMiscCnt_totalCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        p_stats->count = field_value;
        break;

    case CTC_QOS_RESRC_STATS_QUEUE_COUNT:
        CTC_MAX_VALUE_CHECK(p_stats->priority, 15);

        sal_memset(&queue_temp, 0, sizeof(ctc_qos_queue_id_t));
        if (sal_memcmp(&(p_stats->queue), &queue_temp, sizeof(ctc_qos_queue_id_t)))
        {
            sal_memcpy(&queue, &(p_stats->queue), sizeof(ctc_qos_queue_id_t));
        }
        else
        {
            queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
            queue.gport = p_stats->gport;
            queue.queue_id = p_stats->priority / 2;
        }

        CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip, &queue, &queue_id));

        if (snapshot_en)
        {
            cmd = DRV_IOR(DsErmQueueCntShadow_t, DsErmQueueCntShadow_queueCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &field_value));
        }
        else
        {
            cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &field_value));
        }
        p_stats->count = field_value;
        break;

    case CTC_QOS_RESRC_STATS_IGS_PORT_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        if (!SYS_IS_NETWORK_CHANNEL(chan_id))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        cmd = DRV_IOR(DsIrmPortCnt_t, DsIrmPortCnt_portCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_value));
        p_stats->count = field_value;
        break;

    case CTC_QOS_RESRC_STATS_EGS_PORT_COUNT:
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        if (!SYS_IS_NETWORK_CHANNEL(chan_id))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        if (snapshot_en)
        {
            cmd = DRV_IOR(DsErmPortCntShadow_t, DsErmPortCntShadow_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_value));
        }
        else
        {
            cmd = DRV_IOR(DsErmPortCnt_t, DsErmPortCnt_portCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_value));
        }
        p_stats->count = field_value;
        break;
    case CTC_QOS_RESRC_STATS_PRI_CLASS_COUNT:
        CTC_MAX_VALUE_CHECK(p_stats->pri_class, 7);
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_stats->gport, lchip, lport);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        if (!SYS_IS_NETWORK_CHANNEL(chan_id))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
        cmd = DRV_IOR(DsIrmPortTcCnt_t, DRV_FROM_TMM(lchip) ? DsIrmPortTcCnt_portTcCnt_f : DsIrmPortTcCnt_u_g1_portTcCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (chan_id << 3 | p_stats->pri_class), cmd, &field_value));
        p_stats->count = field_value;
        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_resrc_mgr_en(uint8 lchip, uint8 enable)
{
    uint32 cmd        = 0;
    uint32 field_val  = 0;
    field_val = enable ? 1 : 0;

    cmd = DRV_IOW(IrmMiscCtl_t, IrmMiscCtl_resourceCheckEn_f);
    SYS_SET_FIELD_TBL_ALL_DP(lchip, cmd, field_val);

    cmd = DRV_IOW(ErmMiscCtl_t, ErmMiscCtl_resourceCheckEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    return CTC_E_NONE;
}

int32
sys_usw_qos_set_oobfc(uint8 lchip, ctc_qos_oobfc_t* p_oobfc_para)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint16 port_base = 0;
    uint16 port_i = 0;
    uint16 port_cnt = 0;
    uint16 port_max_cnt = 0;
    uint16 port_max_cnt_array[CTC_QOS_OOBFC_MODE_MAX][2] = {{0,32},{256,32},{0,32},{256,32}};
    uint16 index = 0;
    uint32 en_bitmap[16] = {0};
    uint16 port_array[256];
    uint8  step = 0;
    uint8  idx1 = 0;
    uint8  idx2 = 0;
    ds_t ds;
    OobFcPortMap_m port_map;
    OobFcCal_m cal;
    OobFcVecRegWrEn_m ver_reg_wr;
    OobFcReserved_m reserve;

    CTC_MAX_VALUE_CHECK(p_oobfc_para->mode, CTC_QOS_OOBFC_MODE_MAX - 1);

    if(p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_EGRESS || p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_INGRESS)
    {
        if (p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_EGRESS && !p_oobfc_para->is_pfc)
        {
            return CTC_E_INVALID_CONFIG;
        }
        field_val = p_oobfc_para->enable ? 1 : 0;
        cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        SetOobFcRxRcvEn(V, rxRcvEn_f, &ds, field_val);
        cmd = DRV_IOW(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        cmd = DRV_IOR(OobFcCfgRxProc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        SetOobFcCfgRxProc(V, rxFcsChkEn_f, &ds, field_val);
        cmd = DRV_IOW(OobFcCfgRxProc_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        cmd = DRV_IOR(QMgrOobFcCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        SetQMgrOobFcCtl(V, oobFcPriEn_f, &ds, p_oobfc_para->enable && p_oobfc_para->is_pfc ? 1 : 0);
        SetQMgrOobFcCtl(V, oobFcGrpEn_f, &ds, p_oobfc_para->enable && !p_oobfc_para->is_pfc ? 1 : 0);
        cmd = DRV_IOW(QMgrOobFcCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        sal_memset(&reserve, 0,sizeof(reserve));
        if(p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_INGRESS)
        {
            field_val = p_oobfc_para->enable ? (p_oobfc_para->is_pfc ? 0xE : 0xA) : 0;
            SetOobFcReserved(V, reserved_f, &reserve, field_val);
            cmd = DRV_IOW(OobFcReserved_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &reserve));
        }
        else
        {
            field_val = p_oobfc_para->enable ? 0x9 : 0;
            SetOobFcReserved(V, reserved_f, &reserve, field_val);
            cmd = DRV_IOW(OobFcReserved_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &reserve));
        }
    }
    else
    {
        if (!sys_usw_chip_is_local(lchip, p_oobfc_para->gchip_id))
        {
            return CTC_E_INVALID_CHIP_ID;
        }

        idx1 = p_oobfc_para->mode;
        idx2 = p_oobfc_para->is_pfc ? 1 : 0;
        port_max_cnt = port_max_cnt_array[idx1][idx2];
        CTC_MAX_VALUE_CHECK(p_oobfc_para->port_offset, port_max_cnt - 1);

        CTC_BMP_ITER_BEGIN(p_oobfc_para->port_bitmap, port_i)
        {
            if(port_cnt > port_max_cnt - 1 || port_i >= MCHIP_CAP(SYS_CAP_PORT_NUM))
            {
                return CTC_E_INVALID_CONFIG;
            }
            port_array[port_cnt++] = port_i;
            if(!DRV_FROM_TMM(lchip) && (port_i - port_array[0] >= port_max_cnt))
            {
                return CTC_E_INVALID_CONFIG;
            }
            if (p_oobfc_para->enable)
            {
                if (!p_oobfc_para->is_pfc)
                {
                    field_val = port_i;
                    CTC_BMP_SET(en_bitmap, port_i);
                }
                else
                {
                    field_val = DRV_FROM_TMM(lchip) ? (port_cnt - 1) : (port_i - port_array[0]);
                    for (index = 0; index < 8; index++)
                    {
                        CTC_BMP_SET(en_bitmap, field_val * 8 + index);
                    }
                }
            }
        }
        CTC_BMP_ITER_END(p_oobfc_para->port_bitmap, port_i);
        CTC_MIN_VALUE_CHECK(port_cnt, 1);
        port_base = port_array[0];

        if(p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_INGRESS)
        {
            field_val = p_oobfc_para->enable ? 1 : 0;
            cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetOobFcRxRcvEn(V, txFlowCtlEn_f, &ds, field_val);
            cmd = DRV_IOW(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetIrmMiscCtl(V, localPhyPortResrcEn_f, &ds, field_val);
            field_val = p_oobfc_para->enable && p_oobfc_para->is_pfc ? 1 : 0;
            SetIrmMiscCtl(V, localPhyPortResrcPriEn_f, &ds, field_val);
            cmd = DRV_IOW(IrmMiscCtl_t, DRV_ENTRY_FLAG);
            SYS_SET_TBL_ALL_DP(lchip, cmd, ds);

            cmd = DRV_IOR(OobFcCfgIngsMode_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetOobFcCfgIngsMode(V, localPhyPortPriorityEn_f, &ds, field_val);
            cmd = DRV_IOW(OobFcCfgIngsMode_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetOobFcCfgFlowCtl(V, egsFlowCtrlEn_f, &ds, 0);
            SetOobFcCfgFlowCtl(V, ingsFlowCtrlEn_f, &ds, p_oobfc_para->enable ? 1 : 0);
            cmd = DRV_IOW(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val = p_oobfc_para->enable ? (port_cnt - 1) : 0;
            SetOobFcCfgNum(V, cfgPortNum_f, &ds, field_val);
            cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        }
        else /*CTC_QOS_OOBFC_MODE_TX_EGRESS*/
        {
            if (!p_oobfc_para->is_pfc)
            {
                return CTC_E_INVALID_CONFIG;
            }
            field_val = p_oobfc_para->enable ? 1 : 0;
            cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetOobFcRxRcvEn(V, txFlowCtlEn_f, &ds, field_val);
            cmd = DRV_IOW(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            SetOobFcCfgFlowCtl(V, egsFlowCtrlEn_f, &ds, field_val);
            SetOobFcCfgFlowCtl(V, ingsFlowCtrlEn_f, &ds, 0);
            cmd = DRV_IOW(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val = p_oobfc_para->enable ? (port_cnt - 1) : 0;
            SetOobFcCfgNum(V, cfgChanNum_f, &ds, field_val);
            cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

            SetErmStallUpdateScanCtl(V, stallUpdateScanEn_f, &ds, p_oobfc_para->enable ? 1 : 0);
            SetErmStallUpdateScanCtl(V, stallUpdateScanInterval_f, &ds, 1);
            SetErmStallUpdateScanCtl(V, stallUpdateScanPhyPtrMax_f, &ds, MCHIP_CAP(SYS_CAP_CHANNEL_NUM));
            SetErmStallUpdateScanCtl(V, stallUpdateScanPtrMax_f, &ds, MCHIP_CAP(SYS_CAP_CHANNEL_NUM));
            cmd = DRV_IOW(ErmStallUpdateScanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        }

        /*config calendar*/
        sal_memset(&cal, 0,sizeof(cal));
        if(DRV_FROM_TMM(lchip) && p_oobfc_para->is_pfc && p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_INGRESS)
        {
            sal_memset(&port_map, 0,sizeof(port_map));
            for(index =0; index < port_cnt; index++)
            {
                SetOobFcPortMap(V, data_f, &port_map, p_oobfc_para->enable ? index : 0x3f);
                cmd = DRV_IOW(OobFcPortMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, port_array[index], cmd, &port_map));

                SetOobFcCal(V, calendar_f, &cal, p_oobfc_para->enable ? index : 0);
                cmd = DRV_IOW(OobFcCal_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cal));
            }
        }
        else
        {
            for(index =0; index < port_cnt; index++)
            {
                SetOobFcCal(V, calendar_f, &cal, p_oobfc_para->enable ? port_array[index] : 0);
                cmd = DRV_IOW(OobFcCal_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &cal));
            }
        }

        sal_memset(&ver_reg_wr, 0,sizeof(ver_reg_wr));
        SetOobFcVecRegWrEn(A, vecRegWrEn_f, &ver_reg_wr, en_bitmap);
        cmd = DRV_IOW(OobFcVecRegWrEn_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ver_reg_wr));

        cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        SetIrmMiscCtl(V, localPhyPortResrcBase_f, &ds, p_oobfc_para->enable ? port_base : 0);
        cmd = DRV_IOW(IrmMiscCtl_t, DRV_ENTRY_FLAG);
        SYS_SET_TBL_ALL_DP(lchip, cmd, ds);

        p_usw_queue_master[lchip]->oobfc_group_info.mode = p_oobfc_para->enable ? p_oobfc_para->mode : CTC_QOS_OOBFC_MODE_MAX;
        p_usw_queue_master[lchip]->oobfc_group_info.port_offset = p_oobfc_para->port_offset;
        p_usw_queue_master[lchip]->oobfc_group_info.port_num = p_oobfc_para->enable ? port_cnt : 0;
        p_usw_queue_master[lchip]->oobfc_group_info.port_base = p_oobfc_para->enable ? CTC_MAP_LPORT_TO_GPORT(p_oobfc_para->gchip_id, port_base) : 0;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
    }

    if(!DRV_FROM_TMM(lchip))
    {
        field_val =  p_oobfc_para->enable ? 1 : 0;
        step = SysGpioHsMultiCtl_cfgGpioHs1Sel_f - SysGpioHsMultiCtl_cfgGpioHs0Sel_f;
        cmd = DRV_IOR(SysGpioHsMultiCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        for (index = 0; index < 8; index++)
        {
            SetSysGpioHsMultiCtl(V, cfgGpioHs0Sel_f + index * step, &ds, field_val);
        }
        cmd = DRV_IOW(SysGpioHsMultiCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

        step = QMgrExtPriToCosMapCtl_gExt_1_selCos_f - QMgrExtPriToCosMapCtl_gExt_0_selCos_f;
        cmd = DRV_IOR(QMgrExtPriToCosMapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        for (index = 0; index < 8; index++)
        {
            SetQMgrExtPriToCosMapCtl(V, gExt_0_selCos_f + index * step, &ds, index);
        }
        cmd = DRV_IOW(QMgrExtPriToCosMapCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_get_oobfc(uint8 lchip, ctc_qos_oobfc_t* p_oobfc_para)
{
    uint32 cmd = 0;
    uint32 field_val1 = 0;
    uint32 field_val2 = 0;
    uint32 field_val3 = 0;
    uint32 field_val4 = 0;
    uint16 loop = 0;
    uint16 loop1 = 0;
    ds_t ds;

    if ((p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_EGRESS || p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_EGRESS)
        && !p_oobfc_para->is_pfc)
    {
        return CTC_E_INVALID_CONFIG;
    }
    switch(p_oobfc_para->mode)
    {
    case CTC_QOS_OOBFC_MODE_TX_EGRESS:
        {
            if (!sys_usw_chip_is_local(lchip, p_oobfc_para->gchip_id))
            {
                return CTC_E_INVALID_CHIP_ID;
            }

            cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val1 = GetOobFcRxRcvEn(V, txFlowCtlEn_f, &ds);

            cmd = DRV_IOR(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val2 = GetOobFcCfgFlowCtl(V, egsFlowCtrlEn_f, &ds);

            p_oobfc_para->enable = (field_val1 && field_val2) ? 1 : 0;
        }
        break;
    case CTC_QOS_OOBFC_MODE_TX_INGRESS:
        {
            if (!sys_usw_chip_is_local(lchip, p_oobfc_para->gchip_id))
            {
                return CTC_E_INVALID_CHIP_ID;
            }

            cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val1 = GetOobFcRxRcvEn(V, txFlowCtlEn_f, &ds);

            cmd = DRV_IOR(OobFcCfgFlowCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val2 = GetOobFcCfgFlowCtl(V, ingsFlowCtrlEn_f, &ds);
            if(p_oobfc_para->is_pfc)
            {
                cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
                field_val3 = GetIrmMiscCtl(V, localPhyPortResrcPriEn_f, &ds);

                cmd = DRV_IOR(OobFcCfgIngsMode_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
                field_val4 = GetOobFcCfgIngsMode(V, localPhyPortPriorityEn_f, &ds);

                p_oobfc_para->enable = (field_val1 && field_val2 && (field_val3 || DRV_FROM_TMM(lchip))&& field_val4) ? 1 : 0;
            }
            else
            {
                cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
                field_val3 = GetIrmMiscCtl(V, localPhyPortResrcEn_f, &ds);

                cmd = DRV_IOR(OobFcCfgIngsMode_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
                field_val4 = GetOobFcCfgIngsMode(V, localPhyPortPriorityEn_f, &ds);

                p_oobfc_para->enable = (field_val1 && field_val2 && field_val3 && !field_val4) ? 1 : 0;
            }
        }
        break;
    case CTC_QOS_OOBFC_MODE_RX_EGRESS:
    case CTC_QOS_OOBFC_MODE_RX_INGRESS:
        {
            cmd = DRV_IOR(OobFcRxRcvEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val1 = GetOobFcRxRcvEn(V, rxRcvEn_f, &ds);

            cmd = DRV_IOR(QMgrOobFcCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val2 = GetQMgrOobFcCtl(V, oobFcPriEn_f, &ds);
            field_val3 = GetQMgrOobFcCtl(V, oobFcGrpEn_f, &ds);

            cmd = DRV_IOR(OobFcReserved_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            field_val4 = GetOobFcReserved(V, reserved_f, &ds);

            if((DRV_IS_TSINGMA(lchip) && (SYS_GET_CHIP_VERSION == SYS_CHIP_SUB_VERSION_B)) || DRV_FROM_TMM(lchip))
            {
                if (p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_RX_EGRESS)
                {
                    field_val4 = CTC_IS_BIT_SET(field_val4, 0) && CTC_IS_BIT_SET(field_val4, 3);
                }
                else
                {
                    field_val4 = p_oobfc_para->is_pfc ? CTC_IS_BIT_SET(field_val4, 1) && CTC_IS_BIT_SET(field_val4, 2) && CTC_IS_BIT_SET(field_val4, 3)
                                                      : CTC_IS_BIT_SET(field_val4, 1) && CTC_IS_BIT_SET(field_val4, 3);
                }
            }
            else
            {
                field_val4 = 1;
            }
            if (p_oobfc_para->is_pfc)
            {
                p_oobfc_para->enable = (field_val1 && field_val2) ? 1 : 0;
            }
            else
            {
                p_oobfc_para->enable = (field_val1 && !field_val2 && (field_val3 || DRV_FROM_TMM(lchip)) && field_val4) ? 1 : 0;
            }
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    if(p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_EGRESS || p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_INGRESS)
    {
        for (loop = 0; loop < p_usw_queue_master[lchip]->oobfc_group_info.port_num; loop++)
        {
            cmd = DRV_IOR(OobFcCal_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop, cmd, &ds));
            field_val1 = GetOobFcCal(V, calendar_f, &ds);

            if(DRV_FROM_TMM(lchip) && p_oobfc_para->mode == CTC_QOS_OOBFC_MODE_TX_INGRESS && p_oobfc_para->is_pfc)
            {
                for (loop1 = 0; loop1 < SYS_MAX_OOBFC_INGRESS_PORT_NUM; loop1++)
                {
                    cmd = DRV_IOR(OobFcPortMap_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, loop1, cmd, &ds));
                    field_val2 = GetOobFcPortMap(V, data_f, &ds);
                    if(field_val2 == field_val1)
                    {
                        field_val1 = loop1;
                        break;
                    }
                }

                if(loop1 == SYS_MAX_OOBFC_INGRESS_PORT_NUM)
                {
                    break;
                }
            }
            CTC_BMP_SET(p_oobfc_para->port_bitmap, field_val1);
        }
        p_oobfc_para->gchip_id = CTC_MAP_GPORT_TO_GCHIP(p_usw_queue_master[lchip]->oobfc_group_info.port_base);
        p_oobfc_para->port_offset = p_usw_queue_master[lchip]->oobfc_group_info.port_offset;
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_set_fast_ecn(uint8 lchip, uint32 value)
{
    uint32 cmd = 0;
    EpePktProcCtl_m EpePktProcCtl;

    if(!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    else
    {
        CTC_MAX_VALUE_CHECK(value, MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD));
    }

    cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    SetEpePktProcCtl(V, queueDepthThrd_f, &EpePktProcCtl, value - 1);
    cmd = DRV_IOW(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));

    return CTC_E_NONE;
}

int32
sys_usw_qos_get_fast_ecn(uint8 lchip, uint32* value)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    EpePktProcCtl_m EpePktProcCtl;

    if(!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    CTC_PTR_VALID_CHECK(value);

    cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    field_value = GetEpePktProcCtl(V, queueDepthThrd_f, &EpePktProcCtl);/*17 bit*/
    *value = (field_value + 1) & 0x1FFFF;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_set_resrc_check_mode(uint8 lchip, uint8 mode, uint8 from_init)
{
    uint32 cmd = 0;
    uint32 entry_num = 0;
    uint32 index = 0;
    ErmMiscCtl_m erm_misc_ctl;
    IrmMiscCtl_m irm_misc_ctl;
    DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile;

    if (DRV_FROM_TMM(lchip) && mode)
    {
        return CTC_E_NOT_SUPPORT;
    }

    LCHIP_CHECK(lchip);
    CTC_MAX_VALUE_CHECK(mode, 1);

    sal_memset(&erm_misc_ctl, 0, sizeof(ErmMiscCtl_m));
    sal_memset(&irm_misc_ctl, 0, sizeof(IrmMiscCtl_m));
    sal_memset(&ds_que_thrd_profile, 0, sizeof(DsErmQueueLimitedThrdProfile_m));

    if (mode)
    {
        cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
        SetErmMiscCtl(V, resourceCheckMode_f, &erm_misc_ctl, 1);
        cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    }
    else
    {
        cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
        SetErmMiscCtl(V, resourceCheckMode_f, &erm_misc_ctl, 0);
        cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

        if (!from_init)
        {
            sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueLimitedThrdProfile_t, &entry_num);
            for (index = 0; index < entry_num; index++)
            {
                cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
                SetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedAutoEn_f , &ds_que_thrd_profile, 1);
                SetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedAutoEn_f , &ds_que_thrd_profile, 1);
                SetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedAutoEn_f , &ds_que_thrd_profile, 1);
                SetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedAutoEn_f , &ds_que_thrd_profile, 1);
                cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
            }
        }
    }

    return CTC_E_NONE;
}

/*
* mode 0 : continuous mode
* mode 1 : discrete mode(congest level)
*/
int32
sys_usw_qos_set_resrc_check_mode(uint8 lchip, uint8 mode)
{
    CTC_ERROR_RETURN(_sys_usw_qos_set_resrc_check_mode(lchip, mode, 0));
    p_usw_queue_master[lchip]->resrc_check_mode = mode;
    return CTC_E_NONE;
}

int32
_sys_usw_queue_set_egs_resrc_guarantee(uint8 lchip, uint8 enable)
{
    uint32 cmd = 0;
    uint32 min = 0;
    uint32 field_val = 0;
    uint32 entry_num = 0;
    uint16 index = 0;

    LCHIP_CHECK(lchip);

    if (!DRV_FROM_TMM(lchip))
    {
        min = enable ? 20 : 0;
        field_val = enable ? 0 : 7;
        /*default config port min, not config queue min*/
        /*DsErmQueueGuaranteedThrdProfile_m que_min_profile;
        sal_memset(&que_min_profile, 0, sizeof(DsErmQueueGuaranteedThrdProfile_m));
        cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &que_min_profile));
        SetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f , &que_min_profile, min);
        cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &que_min_profile));
        */

        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &min));

        for (index = 0; index < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) ; index ++)
        {
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_queueGuaranteedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }

    }
    else
    {
        field_val = enable ? 30 : 0x3FF;
        sys_usw_ftm_query_table_entry_num(lchip, DsErmPortGuaranteedThrdProfile_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOW(DsErmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }

        field_val = enable ? 30 : 0x3FF;
        sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueGuaranteedThrdProfile_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DsErmQueueGuaranteedThrdProfile_queueGuaranteedThrd_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_queue_set_resrc_use_cnt_min(uint8 lchip, uint8 min)
{
    uint32 cmd = 0;
    IrmMiscCtl_m irm_misc_ctl;
    ErmMiscCtl_m erm_misc_ctl;

    cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_misc_ctl));
    SetIrmMiscCtl(V, resrcUseCntMin_f , &irm_misc_ctl, min);
    cmd = DRV_IOW(IrmMiscCtl_t, DRV_ENTRY_FLAG);
    SYS_SET_TBL_ALL_DP(lchip, cmd, irm_misc_ctl);

    cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    SetErmMiscCtl(V, resrcUseCntMin_f, &erm_misc_ctl, min);
    cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

    return CTC_E_NONE;
}

int32
sys_usw_qos_flow_ctl_profile(uint8 lchip, uint32 gport,
                                    uint8 priority_class,
                                    uint8 is_pfc,
                                    uint8 is_oobfc,
                                    uint8 enable)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 field_id = 0;
    uint32 field_val = 0;
    uint16 chan_id  = 0;
    uint32 cfg_idx = 0;
    uint32 port_type = 0;
    uint16 lport = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));

    if ((SYS_DMPS_NETWORK_PORT != port_type) && (SYS_DMPS_CPUMAC_NETWORK_PORT != port_type) && !is_oobfc)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " MAC is not used \n");
        return CTC_E_INVALID_CONFIG;
    }

    CTC_ERROR_RETURN(_sys_usw_get_channel_by_port(lchip, gport, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    lport = CTC_MAP_GPORT_TO_LPORT(gport);
    if(is_oobfc)/*ingress oobfc*/
    {
        if(is_pfc)
        {
            cfg_idx = lport - CTC_MAP_GPORT_TO_LPORT(p_usw_queue_master[lchip]->oobfc_group_info.port_base) + SYS_MAX_OOBFC_PORT_CFG_BASE;/*[64,96)*/
        }
        else
        {
            cfg_idx = lport / 8 + SYS_MAX_OOBFC_PORT_CFG_BASE;
        }
        CTC_VALUE_RANGE_CHECK(cfg_idx, 64, 95);
    }
    else
    {
        cfg_idx = chan_id;/*[0,64)*/
    }
    /* 2. modify XON/XOFF threashold */
    if(is_oobfc && ((SYS_DMPS_NETWORK_PORT == port_type) || (SYS_DMPS_CPUMAC_NETWORK_PORT == port_type)))
    {
        field_val = enable ? p_usw_queue_master[lchip]->p_oobfc_profile[chan_id]->index.index : 1;
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile id = %d\n", field_val);
        cmd = DRV_IOW(DsErmPortCfg_t, DsErmPortCfg_portFcThrdProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
    }
    if (is_pfc)
    {

        if (p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][priority_class] != NULL)
        {
            field_val = enable ? p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][priority_class]->profile_id : 1;
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile id = %d\n", field_val);
            field_id = DsIrmPortStallCfg_u_g1_0_portTcFlowControlThrdProfId_f + priority_class;
            index = cfg_idx;
            cmd = DRV_IOW(DsIrmPortStallCfg_t, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }
        if(p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][priority_class] != NULL)
        {
            field_val = enable ? p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][priority_class]->profile_id: 0xf;
            cmd = DRV_IOW(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g1_portTcLimitedThrdProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (cfg_idx << 3) + priority_class, cmd, &field_val));
        }
    }
    else
    {
        /*port threshold profile ID*/
        if(is_oobfc)
        {
            field_val = enable ? p_usw_queue_master[lchip]->p_pfc_profile[cfg_idx][lport % 8]->profile_id : 1;
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile id = %d\n", field_val);
            field_id = DsIrmPortStallCfg_u_g2_0_portFlowControlThrdProfId_f + lport % 8;
            cmd = DRV_IOW(DsIrmPortStallCfg_t, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &field_val));
            if (p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport % 8] != NULL)
            {
                field_val = enable ? p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[cfg_idx][lport % 8]->profile_id: 0xf;
                cmd = DRV_IOW(DsIrmPortTcCfg_t, DsIrmPortTcCfg_u_g2_portLimitedThrdProfId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &field_val));
            }
        }
        else
        {
            field_val = enable ? p_usw_queue_master[lchip]->p_fc_profile[cfg_idx]->profile_id : 1;
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  " profile id = %d\n", field_val);
            field_id = DsIrmPortStallCfg_portFlowControlThrdProfId_f;
            cmd = DRV_IOW(DsIrmPortStallCfg_t, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &field_val));

            if (p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx] != NULL)
            {
                field_val = enable ? p_usw_queue_master[lchip]->p_dropthrd_fc_profile[cfg_idx]->profile_id: 0xf;
                cmd = DRV_IOW(DsIrmPortCfg_t, DsIrmPortCfg_portLimitedThrdProfId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cfg_idx, cmd, &field_val));
            }
        }
    }

    return CTC_E_NONE;
}

/**
 @brief Initialize default queue drop.
*/
STATIC int32
_sys_usw_queue_egs_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    uint8 cng_level                = 0;
    uint8 sc                       = 0;
    uint8 level_num                = 0;
    uint8 profile_index            = 0;
    uint8 is_network               = 0;
    uint16 lport                   = 0;
    uint16 index                   = 0;
    uint32 field_val               = 0;
    uint32 field_id                = 0;
    uint32 cmd                     = 0;
    uint8 priority                 = 0;
    uint8 mcast                    = 0;
    uint32 entry_num               = 0;
    uint32 pool_size[CTC_QOS_EGS_RESRC_POOL_MAX] = {0};
    uint8 cutthrough_enable = 0;
    uint8 control_pool_enable = 0;
    uint8 type_num = 0;
    uint32 total_pool_size = 0;

    ErmMiscCtl_m erm_misc_ctl;
    DsErmScThrd_m erm_sc_thrd;
    DsErmPrioScTcMap_m erm_prio_sc_tc_map;
    DsErmMiscThrd_m erm_misc_thrd;
    DsErmPortCfg_m erm_port_cfg;
#ifndef EMULATION_ENV
    DsErmAqmQueueCfg_m erm_aqm_cfg;
#endif
    ErmAqmQueueScanCtl_m erm_aqm_queue_scan_ctl;
    QWriteCtl_m  q_write_ctl;
    DsErmAqmPortThrd_m aqm_port_thrd;
    DsErmQueueLimitedThrdProfile_m ds_que_thrd_profile;

    CTC_MAX_VALUE_CHECK(p_cfg->resrc_pool.egs_pool_mode,CTC_QOS_RESRC_POOL_MODE_MAX - 1);
    sal_memset(&aqm_port_thrd, 0, sizeof(DsErmAqmPortThrd_m));

    /* 1. Buffer assign, total buffer cell is 15K */
    if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_EGS_RESRC_DEFAULT_POOL] = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE) - 1536;
        /* only check sc|total sc */
        pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL]  = 0;
        pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL]      = 0;
        pool_size[CTC_QOS_EGS_RESRC_CONTROL_POOL]   = 1536;     /* 1.5K */
        pool_size[CTC_QOS_EGS_RESRC_MIN_POOL]       = 0;
        pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]       = 0;
    }
    else if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_MODE1)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.egs_pool_size, sizeof(pool_size));
        if (pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL] || pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL])
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    else if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_MODE2)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.egs_pool_size, sizeof(pool_size));
        if ((pool_size[CTC_QOS_EGS_RESRC_DEFAULT_POOL] == 0)
            || (pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL] == 0)
            || (pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL] == 0)
            || (pool_size[CTC_QOS_EGS_RESRC_CONTROL_POOL] == 0)
            || (pool_size[CTC_QOS_EGS_RESRC_C2C_POOL] == 0))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    else if (p_cfg->resrc_pool.egs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.egs_pool_size, sizeof(pool_size));
    }

    /* if use 16K buffer cells mode ,total pool size should not big than 16K*/
    total_pool_size =  pool_size[CTC_QOS_EGS_RESRC_DEFAULT_POOL] + pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL] +pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL]+
                       pool_size[CTC_QOS_EGS_RESRC_CONTROL_POOL] + pool_size[CTC_QOS_EGS_RESRC_MIN_POOL] +pool_size[CTC_QOS_EGS_RESRC_C2C_POOL];
    if (pool_size[CTC_QOS_EGS_RESRC_DEFAULT_POOL] == 0 || total_pool_size > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE)) /* must have default pool */
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE);
    cutthrough_enable = sys_usw_chip_get_cut_through_en(lchip);
    /* 2. configure register fields for egress resource management*/
    cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

    if (DRV_IS_DUET2(lchip) || (DRV_IS_TSINGMA(lchip) && total_pool_size == 32767) || DRV_IS_TMM(lchip))
    {
        SetErmMiscCtl(V, resrcUseCntMin_f, &erm_misc_ctl, 2);
    }
    else
    {
        SetErmMiscCtl(V, resrcUseCntMin_f, &erm_misc_ctl, 1);
    }
    cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

    /* 3. threshold config, total :15k cells (15*1024) */
    cmd = DRV_IOR(DsErmMiscThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_thrd));
    SetDsErmMiscThrd(V, c2cThrd_f, &erm_misc_thrd, 1024);
    SetDsErmMiscThrd(V, criticalThrd_f, &erm_misc_thrd, 1024);
    SetDsErmMiscThrd(V, spanThrd_f, &erm_misc_thrd, 0x400);
    SetDsErmMiscThrd(V, totalThrd_f, &erm_misc_thrd, total_pool_size);

    cmd = DRV_IOW(DsErmMiscThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_thrd));

    /* 4. sc threshold config, use 2 sc, sc0 : default pool; sc1: span pool*/
    cmd = DRV_IOR(DsErmScThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_sc_thrd));
    SetDsErmScThrd(V, g_0_scThrd_f, &erm_sc_thrd, pool_size[CTC_QOS_EGS_RESRC_DEFAULT_POOL] / 8);
    SetDsErmScThrd(V, g_1_scThrd_f, &erm_sc_thrd, pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL] / 8);
    SetDsErmScThrd(V, g_2_scThrd_f, &erm_sc_thrd, pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL] / 8);
    SetDsErmScThrd(V, g_3_scThrd_f, &erm_sc_thrd, (pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]+pool_size[CTC_QOS_EGS_RESRC_CONTROL_POOL]) / 8);
    SetDsErmScThrd(V, g_0_scEn_f, &erm_sc_thrd, 1);
    SetDsErmScThrd(V, g_1_scEn_f, &erm_sc_thrd, pool_size[CTC_QOS_EGS_RESRC_NON_DROP_POOL] ? 1 : 0);
    SetDsErmScThrd(V, g_2_scEn_f, &erm_sc_thrd, pool_size[CTC_QOS_EGS_RESRC_SPAN_POOL] ? 1 : 0);
    if(DRV_IS_DUET2(lchip) && cutthrough_enable)
    {
        SetDsErmScThrd(V, g_0_scEn_f, &erm_sc_thrd, 0);
        SetDsErmScThrd(V, g_1_scEn_f, &erm_sc_thrd, 0);
        SetDsErmScThrd(V, g_2_scEn_f, &erm_sc_thrd, 0);
    }
    SetDsErmScThrd(V, g_3_scEn_f, &erm_sc_thrd, (pool_size[CTC_QOS_EGS_RESRC_C2C_POOL]+pool_size[CTC_QOS_EGS_RESRC_CONTROL_POOL]) ? 1 : 0);
    SetDsErmScThrd(V, g_0_scCngThrd_f, &erm_sc_thrd, 0x7ff);
    SetDsErmScThrd(V, g_1_scCngThrd_f, &erm_sc_thrd, 0x7ff);
    SetDsErmScThrd(V, g_2_scCngThrd_f, &erm_sc_thrd, 0x7ff);
    SetDsErmScThrd(V, g_3_scCngThrd_f, &erm_sc_thrd, 0x7ff);
    SetDsErmScThrd(V, g_0_scCngEn_f, &erm_sc_thrd, 0);
    SetDsErmScThrd(V, g_1_scCngEn_f, &erm_sc_thrd, 0);
    SetDsErmScThrd(V, g_2_scCngEn_f, &erm_sc_thrd, 0);
    SetDsErmScThrd(V, g_3_scCngEn_f, &erm_sc_thrd, 0);
    cmd = DRV_IOW(DsErmScThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_sc_thrd));

    /* 5. mapping profiles, use profile 0/1: all priority mapped to tc priority/2, default use sc 0*/
    profile_index = 0;
    for (sc = 0; sc < 4; sc ++)
    {
        if(p_cfg->resrc_pool.drop_profile[sc].congest_level_num > MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM))
        {
            return CTC_E_INVALID_PARAM;
        }
        if (p_cfg->resrc_pool.drop_profile[sc].congest_level_num == 0)
        {
            p_cfg->resrc_pool.drop_profile[sc].congest_level_num = 1;
        }
        if (pool_size[sc])
        {
            p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num = DRV_FROM_TMM(lchip) ? 1 : p_cfg->resrc_pool.drop_profile[sc].congest_level_num;
            p_usw_queue_master[lchip]->egs_pool[sc].default_profile_id = (p_usw_queue_master[lchip]->resrc_check_mode != 0)?profile_index:0;
            profile_index ++;
        }
    }

    type_num = DRV_FROM_TMM(lchip) ? SYS_QUE_MAP_TYPE_MAX_NUM : 2;
    for (mcast = 0; mcast < type_num; mcast++)
    {
        for (priority = 0; priority < 16; priority++)
        {
            index = mcast << 4 | priority;
            if (mcast && p_usw_queue_master[lchip]->egs_pool[CTC_QOS_EGS_RESRC_SPAN_POOL].egs_congest_level_num)
            {
                sc = CTC_QOS_EGS_RESRC_SPAN_POOL;
            }
            else
            {
                sc = CTC_QOS_EGS_RESRC_DEFAULT_POOL;
            }
            field_val = priority / 2;
            cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
            SetDsErmPrioScTcMap(V, g2_0_mappedTc_f, &erm_prio_sc_tc_map, field_val);
            SetDsErmPrioScTcMap(V, g1_0_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_1_mappedTc_f, &erm_prio_sc_tc_map, field_val);
            SetDsErmPrioScTcMap(V, g1_1_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_3_mappedTc_f, &erm_prio_sc_tc_map, (DRV_FROM_TMM(lchip) || field_val < 6) ? field_val : 6);
            SetDsErmPrioScTcMap(V, g1_3_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_4_mappedTc_f, &erm_prio_sc_tc_map, field_val);
            SetDsErmPrioScTcMap(V, g1_4_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_5_mappedTc_f, &erm_prio_sc_tc_map, field_val);
            SetDsErmPrioScTcMap(V, g1_5_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_6_mappedTc_f, &erm_prio_sc_tc_map, (!DRV_FROM_TMM(lchip) || field_val < 6) ? field_val : 6);
            SetDsErmPrioScTcMap(V, g1_6_mappedSc_f , &erm_prio_sc_tc_map, sc);
            SetDsErmPrioScTcMap(V, g2_7_mappedTc_f, &erm_prio_sc_tc_map, field_val);
            SetDsErmPrioScTcMap(V, g1_7_mappedSc_f , &erm_prio_sc_tc_map, sc);
            cmd = DRV_IOW(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
        }
    }

    /* cirtical packet use profile 2*/
    control_pool_enable = (p_usw_queue_master[lchip]->egs_pool[CTC_QOS_EGS_RESRC_CONTROL_POOL].egs_congest_level_num)? (DRV_FROM_TMM(lchip) ? 8 : 2) : 0;
    for (mcast = 0; mcast < control_pool_enable; mcast++)
    {
        for (priority = 0; priority < 16; priority++)
        {
            index = mcast << 4 | priority;
            sc = CTC_QOS_EGS_RESRC_CONTROL_POOL;
            cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
            SetDsErmPrioScTcMap(V, g2_2_mappedTc_f, &erm_prio_sc_tc_map,(!DRV_FROM_TMM(lchip) || mcast == SYS_QUE_MAP_TYPE_C2C) ? ((priority > 7)?(priority-8) : priority) : (priority / 2));
            SetDsErmPrioScTcMap(V, g1_2_mappedSc_f , &erm_prio_sc_tc_map, sc);
            cmd = DRV_IOW(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
        }
    }
    field_val = 2;
    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0), cmd, &field_val));
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX1), cmd, &field_val));
    field_val = DRV_FROM_TMM(lchip) ? 0 : 2;
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX2), cmd, &field_val));
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, MCHIP_CAP(SYS_CAP_CHANID_DMA_RX3), cmd, &field_val));

    /*cpu mac*/
    field_val = 2;
    if (MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
    {
        uint16 cpu_mac_channel[SYS_USW_CPU_MAC_NUM] = {MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1),
                                                                  MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC3)};
        for(index = 0; index < SYS_USW_CPU_MAC_NUM; index++)
        {
            MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,index,&lport,&is_network);
            if(!is_network)
            {
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, cpu_mac_channel[index], cmd, &field_val));
            }
        }
    }

    if(!DRV_FROM_TMM(lchip))
    {
        /* 6. config congestion level to enable self-tuning threshold
         *    TMM no congestion level
         */
        for (sc = 0; sc < 4; sc ++)
        {
            if(p_cfg->resrc_pool.drop_profile[sc].congest_level_num > MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM))
            {
                return CTC_E_INVALID_PARAM;
            }
            if (p_cfg->resrc_pool.drop_profile[sc].congest_level_num == 0)
            {
                p_cfg->resrc_pool.drop_profile[sc].congest_level_num = 1;
            }
            level_num = p_cfg->resrc_pool.drop_profile[sc].congest_level_num - 1;

            for (cng_level = 0; cng_level < level_num; cng_level ++)
            {
                field_val = p_cfg->resrc_pool.drop_profile[sc].congest_threshold[cng_level] / 32;
                field_id = DsErmScCngThrdProfile_g_0_scCngThrd_f + cng_level + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM) - 1 -level_num);
                cmd = DRV_IOW(DsErmScCngThrdProfile_t, field_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, sc, cmd, &field_val));
            }
        }
        /* 7. coutthrough mode use port thrd */
        if(DRV_IS_DUET2(lchip) && cutthrough_enable)
        {
            for(index = 0;index < 4;index ++)
            {
                field_val = 128;
                field_id = DsErmPortLimitedThrdProfile_g_0_portLimitedThrd_f + 3*index;
                cmd = DRV_IOW(DsErmPortLimitedThrdProfile_t, field_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 60, cmd, &field_val));
            }
        }

        /* TM:default enable queue guarantee,TMM:default disable queue guarantee*/
        for (index = 0; index < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) ; index ++)
        {
            field_val = 0;
            field_id = DsErmQueueCfg_queueGuaranteedThrdProfId_f;
            cmd = DRV_IOW(DsErmQueueCfg_t, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }

#if 0 /*default use port min, not use queue min*/
        /* 7. config queue minimum guarantee profile 0: 20 cells*/
        DsErmQueueGuaranteedThrdProfile_m que_min_profile;
        sal_memset(&que_min_profile, 0, sizeof(DsErmQueueGuaranteedThrdProfile_m));

        cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &que_min_profile));
        SetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f , &que_min_profile, 20);
        cmd = DRV_IOW(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &que_min_profile));

        for (index = 0; index < 1280; index ++)
        {
            field_val = 0;
            field_id = DsErmQueueCfg_queueGuaranteedThrdProfId_f;
            cmd = DRV_IOW(DsErmQueueCfg_t, field_id);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }
#endif
        /* 8. configure port minimum guarantee profile, default all use profile id 0: port Min = 20*/
        field_val = 20;
        cmd = DRV_IOW(DsErmPortGuaranteedThrdProfile_t, DsErmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        for (lport = 0; lport < 64; lport++)
        {
            field_val = 0;
            field_id = DsErmPortCfg_portGuaranteedThrdProfId_f;
            cmd = DRV_IOW(DsErmPortCfg_t, field_id);
            index = lport;
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }

        /* 9. disable port limited thrd check, port threshold profile alawy be 0*/
        sys_usw_ftm_query_table_entry_num(lchip, DsErmPortCfg_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOR(DsErmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_port_cfg));
            SetDsErmPortCfg(V, portLimitedThrdProfId_f, &erm_port_cfg, 0xF);
            cmd = DRV_IOW(DsErmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_port_cfg));
        }

#ifndef EMULATION_ENV
        /* 10, disable wred mode, default wtd mode, wred mode only support base queue(512) and extend queue(256)*/
        sys_usw_ftm_query_table_entry_num(lchip, DsErmAqmQueueCfg_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
            SetDsErmAqmQueueCfg(V, queueThrdProfId_f, &erm_aqm_cfg, MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM));
            cmd = DRV_IOW(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_cfg));
        }
#endif

        /* 11, config port congestion thrd*/
        cmd = DRV_IOR(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));
        SetQWriteCtl(V, portCongestionThrd_f, &q_write_ctl, 20);
        cmd = DRV_IOW(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));
    }
    /* 12, diable  port aqm*/
    field_val = (DRV_IS_DUET2(lchip)) ? 0x3FFF : 0xFFFFFF;
    SetDsErmAqmPortThrd(V, aqmPortThrdHigh_f, &aqm_port_thrd, DRV_FROM_TMM(lchip) ? 0 : field_val);
    SetDsErmAqmPortThrd(V, aqmPortThrdLow_f, &aqm_port_thrd, field_val);
    cmd = DRV_IOW(DsErmAqmPortThrd_t, DRV_ENTRY_FLAG);
    for (index = 0; index < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); index++)
    {
        if (!SYS_IS_NETWORK_CHANNEL(index))
        {
            continue;
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &aqm_port_thrd));
    }

    /* 13, enable aqm queue scan*/
    field_val = DRV_FROM_TMM(lchip) ? MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) : ((DRV_IS_DUET2(lchip)) ? 767 : 3583);
    cmd = DRV_IOR(ErmAqmQueueScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_aqm_queue_scan_ctl));
    SetErmAqmQueueScanCtl(V, aqmQueueScanEn_f , &erm_aqm_queue_scan_ctl, 1);
    SetErmAqmQueueScanCtl(V, aqmQueueScanInterval_f, &erm_aqm_queue_scan_ctl, DRV_FROM_TMM(lchip) ? 1 : 10);
    SetErmAqmQueueScanCtl(V, aqmQueueScanPtrMax_f, &erm_aqm_queue_scan_ctl, field_val);
    SetErmAqmQueueScanCtl(V, aqmQueueScanPhyPtrMax_f, &erm_aqm_queue_scan_ctl, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM));
    cmd = DRV_IOW(ErmAqmQueueScanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_aqm_queue_scan_ctl));

    /* 14, default disable ecn mark*/
    if(!DRV_FROM_TMM(lchip))
    {
        field_val = (DRV_IS_DUET2(lchip)) ? 0x7FF : 0xFFF;
        for (cng_level = 0; cng_level < 4; cng_level++)
        {
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            index = (MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM) << 2) + cng_level;
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
            SetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
            SetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
            SetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
            SetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &ds_que_thrd_profile, field_val);
            cmd = DRV_IOW(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            index = (MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM) << 2) + cng_level;
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds_que_thrd_profile));
        }
    }

    /* 15, set resrc check mode*/
    if(!(CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING))
    {
        CTC_ERROR_RETURN(_sys_usw_qos_set_resrc_check_mode(lchip, p_usw_queue_master[lchip]->resrc_check_mode, 1));
    }
    return CTC_E_NONE;
}

extern int32
_sys_usw_queue_igs_resrc_mgr_init(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    uint32 cmd                     = 0;
    uint16 lport                   = 0;
    uint8 priority                 = 0;
    uint16 index                    = 0;
    uint8 cng_level                = 0;
    uint32 field_id                = 0;
    uint32 field_val               = 0;
    uint8 mcast                    = 0;
    uint8 dp                       = 0;
    uint32 entry_num               = 0;
    uint8 cutthrough_enable        = 0;
    uint8 sc                       = 0;
    uint32 pool_size[CTC_QOS_IGS_RESRC_POOL_MAX] = {0};
    uint32 total_pool_size = 0;

    IrmMiscCtl_m irm_misc_ctl;
    DsIrmMiscThrd_m irm_misc_thrd;
    DsIrmScThrd_m irm_sc_thrd;
    DsIrmPrioScTcMap_m irm_prio_sc_tc_map;
    DsIrmPortCfg_m irm_port_cfg;
    DsIrmPortTcCfg_m irm_port_tc_cfg;

    sal_memset(&irm_misc_ctl, 0, sizeof(IrmMiscCtl_m));
    sal_memset(&irm_misc_thrd, 0, sizeof(DsIrmMiscThrd_m));
    sal_memset(&irm_sc_thrd, 0, sizeof(DsIrmScThrd_m));
    sal_memset(&irm_prio_sc_tc_map, 0, sizeof(DsIrmPrioScTcMap_m));
    sal_memset(&irm_port_cfg, 0, sizeof(DsIrmPortCfg_m));
    sal_memset(&irm_port_tc_cfg, 0, sizeof(DsIrmPortTcCfg_m));

    CTC_MAX_VALUE_CHECK(p_cfg->resrc_pool.igs_pool_mode,CTC_QOS_RESRC_POOL_MODE_MAX - 1);

    /* 1. Buffer assign, total buffer cell is 15K */
    if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        pool_size[CTC_QOS_IGS_RESRC_DEFAULT_POOL] = MCHIP_CAP(SYS_CAP_QOS_DROP_IGS_DEFAULT_POOL_SIZE);
        pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL]  = 0;
        pool_size[CTC_QOS_IGS_RESRC_MIN_POOL]       = DRV_IS_TMG(lchip) ? 2560 : (DRV_FROM_TMM(lchip) ? 7680 : 1280);     /*64*20*/
        pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]       = 1280;
        pool_size[CTC_QOS_IGS_RESRC_ROUND_TRIP_POOL]= 0;
        pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]   = 1280;
    }
    else if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_MODE1)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.igs_pool_size, sizeof(pool_size));
        if (pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL] || pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL])
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    else if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_MODE2)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.igs_pool_size, sizeof(pool_size));
        if ((pool_size[CTC_QOS_IGS_RESRC_DEFAULT_POOL] == 0)
            || (pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL] == 0)
            || (pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL] == 0)
            || (pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL] == 0)
            || (pool_size[CTC_QOS_IGS_RESRC_C2C_POOL] == 0))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    else if (p_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_USER_DEFINE)
    {
        sal_memcpy(pool_size, p_cfg->resrc_pool.igs_pool_size, sizeof(pool_size));
    }

    /* if use 16K buffer cells mode ,total pool size should not big than 16K*/
    total_pool_size =  pool_size[CTC_QOS_IGS_RESRC_DEFAULT_POOL] + pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL] +pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL]+
                       pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL] + pool_size[CTC_QOS_IGS_RESRC_MIN_POOL] +pool_size[CTC_QOS_IGS_RESRC_C2C_POOL];
    if (pool_size[CTC_QOS_IGS_RESRC_DEFAULT_POOL] == 0 || total_pool_size > MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE)) /* must have default pool */
    {
        return CTC_E_INVALID_PARAM;
    }

    total_pool_size = MCHIP_CAP(SYS_CAP_QOS_DROP_TOTAL_POOL_SIZE);
    /* 2. enable ingress resource management*/
    cmd = DRV_IOR(IrmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_misc_ctl));
    if(DRV_IS_DUET2(lchip) || (DRV_IS_TSINGMA(lchip) &&  total_pool_size == 32767) || DRV_IS_TMM(lchip))
    {
        SetIrmMiscCtl(V, resrcUseCntMin_f , &irm_misc_ctl, 2);
    }
    else
    {
        SetIrmMiscCtl(V, resrcUseCntMin_f , &irm_misc_ctl, 1);
    }
    SetIrmMiscCtl(V, flowControlUsePortCnt_f, &irm_misc_ctl, DRV_IS_TMG(lchip) ? 1 : 0);
    cmd = DRV_IOW(IrmMiscCtl_t, DRV_ENTRY_FLAG);
    SYS_SET_TBL_ALL_DP(lchip, cmd, irm_misc_ctl);

    /* 3. threshold config, total :15k cells (15*1024) */
    cmd = DRV_IOR(DsIrmMiscThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_misc_thrd));
    SetDsIrmMiscThrd(V, c2cThrd_f, &irm_misc_thrd, pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]);
    SetDsIrmMiscThrd(V, criticalThrd_f, &irm_misc_thrd, pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL]);
    SetDsIrmMiscThrd(V, totalThrd_f, &irm_misc_thrd, total_pool_size);
   
    cmd = DRV_IOW(DsIrmMiscThrd_t, DRV_ENTRY_FLAG);
    SYS_SET_TBL_ALL_DP(lchip, cmd, irm_misc_thrd);

    /* 4. configure default pool threshold*/
    /*sc0:default pool*/
    cutthrough_enable = sys_usw_chip_get_cut_through_en(lchip);
    cmd = DRV_IOR(DsIrmScThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_sc_thrd));
    SetDsIrmScThrd(V, scEn_f, &irm_sc_thrd, cutthrough_enable ? 0 : 1);
    SetDsIrmScThrd(V, scThrd_f, &irm_sc_thrd, (pool_size[CTC_QOS_IGS_RESRC_DEFAULT_POOL]+pool_size[CTC_QOS_IGS_RESRC_C2C_POOL]
                   +pool_size[CTC_QOS_IGS_RESRC_CONTROL_POOL])/ (DRV_FROM_TMM(lchip) ? 1 : 8));
    cmd = DRV_IOW(DsIrmScThrd_t, DRV_ENTRY_FLAG);
    for (dp = 0; dp < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp++)
    {
        index = dp << 2 | CTC_QOS_IGS_RESRC_DEFAULT_POOL;
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_sc_thrd));
    }

    /*sc1:non-drop pool*/
    SetDsIrmScThrd(V, scEn_f, &irm_sc_thrd, cutthrough_enable || pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL] == 0 ? 0 : 1);
    SetDsIrmScThrd(V, scThrd_f, &irm_sc_thrd, pool_size[CTC_QOS_IGS_RESRC_NON_DROP_POOL] / (DRV_FROM_TMM(lchip) ? 1 : 8));
    cmd = DRV_IOW(DsIrmScThrd_t, DRV_ENTRY_FLAG);
    for (dp = 0; dp < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp++)
    {
        index = dp << 2 | CTC_QOS_IGS_RESRC_NON_DROP_POOL;
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_sc_thrd));
    }

    /*sc2:span pool*/
    SetDsIrmScThrd(V, scEn_f, &irm_sc_thrd, cutthrough_enable || pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL] == 0 ? 0 : 1);
    SetDsIrmScThrd(V, scThrd_f, &irm_sc_thrd, pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL] / (DRV_FROM_TMM(lchip) ? 1 : 8));
    cmd = DRV_IOW(DsIrmScThrd_t, DRV_ENTRY_FLAG);
    for (dp = 0; dp < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp++)
    {
        index = dp << 2 | CTC_QOS_IGS_RESRC_SPAN_POOL;
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_sc_thrd));
    }

    /* 5. mapping profiles, only use profile 0: all priority mapped to tc priority/2 and sc 0 */
    for (dp = 0; dp < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dp++)
    {
        for (mcast = 0; mcast < 2; mcast++)
        {
            for (priority = 0; priority < 16; priority++)
            {
                index = dp << 5 | mcast << 4 | priority;
                if (mcast && pool_size[CTC_QOS_IGS_RESRC_SPAN_POOL])
                {
                    sc = CTC_QOS_IGS_RESRC_SPAN_POOL;
                }
                else
                {
                    sc = CTC_QOS_IGS_RESRC_DEFAULT_POOL;
                }
                cmd = DRV_IOR(DsIrmPrioScTcMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_prio_sc_tc_map));
                SetDsIrmPrioScTcMap(V, g2_0_mappedTc_f, &irm_prio_sc_tc_map, priority / 2);
                SetDsIrmPrioScTcMap(V, g2_0_portTcEn_f, &irm_prio_sc_tc_map, (sc == CTC_QOS_IGS_RESRC_SPAN_POOL) ? 0 : 1);
                SetDsIrmPrioScTcMap(V, g1_0_mappedSc_f , &irm_prio_sc_tc_map, sc);
                SetDsIrmPrioScTcMap(V, g2_1_mappedTc_f, &irm_prio_sc_tc_map, priority / 2);
                SetDsIrmPrioScTcMap(V, g2_1_portTcEn_f, &irm_prio_sc_tc_map, (sc == CTC_QOS_IGS_RESRC_SPAN_POOL) ? 0 : 1);
                SetDsIrmPrioScTcMap(V, g1_1_mappedSc_f , &irm_prio_sc_tc_map, sc);
                cmd = DRV_IOW(DsIrmPrioScTcMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_prio_sc_tc_map));
            }
        }
    }
#if 0 /*default use port min, not use portTc min*/
    /* 6. configure portTc minimum guarantee profile, profile 0: portTc Min = 20*/
    DsIrmPortTcGuaranteedThrdProfile_m igr_port_tc_min_profile;
    sal_memset(&igr_port_tc_min_profile, 0, sizeof(DsIrmPortTcGuaranteedThrdProfile_m));
    cmd = DRV_IOR(DsIrmPortTcGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &igr_port_tc_min_profile));
    SetDsIrmPortTcGuaranteedThrdProfile(V, portTcGuaranteedThrd_f, &igr_port_tc_min_profile, 20);
    cmd = DRV_IOW(DsIrmPortTcGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &igr_port_tc_min_profile));

    /* default all use profile id 0 */
    for (lport = 0; lport < 64; lport++)
    {
        for (tc = 0; tc < 8; tc++)
        {
            field_val = 0;
            field_id = DsIrmPortTcCfg_u_g1_portTcGuaranteedThrdProfId_f;
            cmd = DRV_IOW(DsIrmPortTcCfg_t, field_id);
            index = lport << 3 | tc;
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &field_val));
        }
    }
#endif
    /* 7. configure port minimum guarantee profile, default all use profile id 0: port Min = 20
     *    TMM no profile, 1:1
     */
    if(!DRV_FROM_TMM(lchip))
    {
        field_val = 20;
        cmd = DRV_IOW(DsIrmPortGuaranteedThrdProfile_t, DsIrmPortGuaranteedThrdProfile_portGuaranteedThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        for (lport = 0; lport < 64; lport++)
        {
            field_val = 0;
            field_id = DsIrmPortCfg_portGuaranteedThrdProfId_f;
            cmd = DRV_IOW(DsIrmPortCfg_t, field_id);
            index = lport;
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        }

        /* 8. configure SC0 congestion level watermarks, disable ingress congest level_base
         *    TMM no congestion level
         */
        for (cng_level = 0; cng_level < 3; cng_level++)
        {
            field_val = (DRV_IS_DUET2(lchip)) ? 0x1FF : 0x3FF; /*aways in congest level 0*/
            cmd = DRV_IOW(DsIrmScCngThrdProfile_t, DsIrmScCngThrdProfile_g_0_scCngThrd_f + cng_level);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        }

        /* 9. disable port limited thrd check*/
        sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortCfg_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOR(DsIrmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_port_cfg));
            SetDsIrmPortCfg(V, portLimitedThrdProfId_f, &irm_port_cfg, 0xF);
            cmd = DRV_IOW(DsIrmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_port_cfg));
        }

        /* 10. disable portTc limited thrd check*/
        sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortTcCfg_t, &entry_num);
        for (index = 0; index < entry_num; index++)
        {
            cmd = DRV_IOR(DsIrmPortTcCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_port_tc_cfg));
            SetDsIrmPortTcCfg(V, u_g1_portTcLimitedThrdProfId_f, &irm_port_tc_cfg, 0xF);
            SetDsIrmPortTcCfg(V, u_g2_portLimitedThrdProfId_f, &irm_port_tc_cfg, 0xF);
            cmd = DRV_IOW(DsIrmPortTcCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &irm_port_tc_cfg));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_get_profile_from_hw(uint8 lchip, uint32 gport, sys_qos_shape_profile_t* p_shp_profile)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32  chan_id = 0;
    uint32 table_index = 0;
    uint16  group_id = 0;
    uint8  queue_offset = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsQMgrNetChanShpProfile_m net_chan_shp_profile;

    CTC_PTR_VALID_CHECK(p_shp_profile);

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    /*Get chan shaping profile*/
    sal_memset(&net_chan_shp_profile, 0, sizeof(DsQMgrNetChanShpProfile_m));
    cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile));
    p_shp_profile->chan_shp_tokenThrd = GetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile);
    p_shp_profile->chan_shp_tokenThrdShift = GetDsQMgrNetChanShpProfile(V, tokenThrdShift_f, &net_chan_shp_profile);
    if ((MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD) != p_shp_profile->chan_shp_tokenThrd) || (MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFT) != p_shp_profile->chan_shp_tokenThrdShift))
    {
        p_usw_queue_master[lchip]->store_chan_shp_en = 1;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
    }
    if (DRV_IS_TSINGMA(lchip))
    {
        return CTC_E_NONE;
    }
    /*Get base/ctl queue shaping profile*/
    for (queue_offset = 0; queue_offset < SYS_MAX_QUEUE_OFFSET_PER_NETWORK_CHANNEL; queue_offset++)
    {
        table_index = (queue_offset < 8) ? (chan_id*8 + queue_offset)
        : (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC) + chan_id * 4 + (queue_offset - 8));
        cmd = DRV_IOR(DsQMgrNetQueShpProfId_t, DsQMgrNetQueShpProfId_profId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, table_index, cmd, &field_val));
        p_shp_profile->queue_shp_profileId[queue_offset] = field_val;
        if (field_val != 0)
        {
            p_usw_queue_master[lchip]->store_que_shp_en = 1;
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
        }
    }

    /*Get extend group/queue shaping profile*/
    for (group_id = 0; group_id < MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM); group_id++)
    {
        cmd = DRV_IOR(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        if (field_val == chan_id)
        {
            cmd = DRV_IOR(DsQMgrExtGrpShpProfId_t, DsQMgrExtGrpShpProfId_profId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
            p_shp_profile->ext_grp_shp_profileId = field_val;

            for (queue_offset = 0; queue_offset < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP); queue_offset++)
            {
                cmd = DRV_IOR(DsQMgrExtQueShpProfId_t, DsQMgrExtQueShpProfId_profId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (group_id*MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) + queue_offset), cmd, &field_val));
                p_shp_profile->ext_queue_shp_profileId[queue_offset] = field_val;
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_set_port_drop_en(uint8 lchip, uint32 chan_id, bool enable, sys_qos_shape_profile_t* p_shp_profile)
{
    uint32 cmd                     = 0;
    uint32 field_val               = 0;
    uint32 table_index = 0;
    uint16  group_id = 0;
    uint8  queue_offset = 0;
    DsErmPortCfg_m port_cfg;
    QMgrEnqReserved_m enq_rsv;
    DsQMgrNetChanShpProfile_m net_chan_shp_profile;
    sal_memset(&net_chan_shp_profile, 0, sizeof(DsQMgrNetChanShpProfile_m));

    CTC_PTR_VALID_CHECK(p_shp_profile);

    if (MCHIP_QOS(lchip)->qos_queue_set_port_drop_en)
    {
        return MCHIP_QOS(lchip)->qos_queue_set_port_drop_en(lchip, chan_id, enable);
    }

    if (enable)
    {
        /*1. Enable Drop incoming channel packets*/
        cmd = DRV_IOR(DsErmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &port_cfg));
        p_usw_queue_master[lchip]->p_chan_guar_profileid[chan_id] = GetDsErmPortCfg(V, portGuaranteedThrdProfId_f, &port_cfg);
        SetDsErmPortCfg(V, portLimitedThrdProfId_f, &port_cfg, 0);
        SetDsErmPortCfg(V, portGuaranteedThrdProfId_f, &port_cfg, 7);
        cmd = DRV_IOW(DsErmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &port_cfg));

        /*1.1 disable queue guarantee*/
        cmd = DRV_IOR(QMgrEnqReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &enq_rsv));
        field_val = GetQMgrEnqReserved(V, reserved_f, &enq_rsv);
        SetQMgrEnqReserved(V, reserved_f, &enq_rsv, field_val & 0xE7);/*clear bit 3 and 4*/
        cmd = DRV_IOW(QMgrEnqReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &enq_rsv));

        /*2. Disable channel/queue/grp shaping */
        /*Disable chan shaping*/
        if (p_usw_queue_master[lchip]->store_chan_shp_en)
        {
            cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile));
            SetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD));
            SetDsQMgrNetChanShpProfile(V, tokenThrdShift_f  , &net_chan_shp_profile, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFT));
            cmd = DRV_IOW(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile));
        }
        if (DRV_IS_TSINGMA(lchip))
        {
            field_val = 1;
            cmd = DRV_IOW(DsQMgrNetChanMiscCfg_t, DsQMgrNetChanMiscCfg_flushValid_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));

            return CTC_E_NONE;
        }
        /*Disable base/ctl queue shaping*/
        if (p_usw_queue_master[lchip]->store_que_shp_en)
        {
            for (queue_offset = 0; queue_offset < SYS_MAX_QUEUE_OFFSET_PER_NETWORK_CHANNEL; queue_offset++)
            {
                field_val = 0;
                table_index = (queue_offset < 8) ? (chan_id * 8 + queue_offset)
                : (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC) + chan_id * 4 + (queue_offset - 8));
                cmd = DRV_IOW(DsQMgrNetQueShpProfId_t, DsQMgrNetQueShpProfId_profId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, table_index, cmd, &field_val));
            }
        }

        /*Disable extend group/queue shaping*/
        for (group_id = 0; group_id < MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM); group_id++)
        {
            cmd = DRV_IOR(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
            if (field_val == chan_id)
            {
                field_val = 0;
                cmd = DRV_IOW(DsQMgrExtGrpShpProfId_t, DsQMgrExtGrpShpProfId_profId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));

                for (queue_offset = 0; queue_offset < SYS_MAX_QUEUE_OFFSET_PER_EXT_GROUP; queue_offset++)
                {
                    field_val = 0;
                    cmd = DRV_IOW(DsQMgrExtQueShpProfId_t, DsQMgrExtQueShpProfId_profId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (group_id*4 + queue_offset), cmd, &field_val));
                }
            }
        }
    }
    else
    {
        /*1. Enable channel/queue/grp shaping*/
        /*Enable chan shaping*/
        if (p_usw_queue_master[lchip]->store_chan_shp_en)
        {
            cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile));
            SetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile, p_shp_profile->chan_shp_tokenThrd);
            SetDsQMgrNetChanShpProfile(V, tokenThrdShift_f  , &net_chan_shp_profile, p_shp_profile->chan_shp_tokenThrdShift);
            cmd = DRV_IOW(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile));
        }
        if (DRV_IS_DUET2(lchip))
        {
            /*Enable base/ctl queue shaping*/
            if (p_usw_queue_master[lchip]->store_que_shp_en)
            {
                for (queue_offset = 0; queue_offset < SYS_MAX_QUEUE_OFFSET_PER_NETWORK_CHANNEL; queue_offset++)
                {
                    field_val = p_shp_profile->queue_shp_profileId[queue_offset];
                    table_index = (queue_offset < 8) ? (chan_id * 8 + queue_offset)
                    : (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC) + chan_id * 4 + (queue_offset - 8));
                    cmd = DRV_IOW(DsQMgrNetQueShpProfId_t, DsQMgrNetQueShpProfId_profId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, table_index, cmd, &field_val));
                }
            }

            /*Enable extend group/queue shaping*/
            for (group_id = 0; group_id < MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM); group_id++)
            {
                cmd = DRV_IOR(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
                if (field_val == chan_id)
                {
                    field_val = p_shp_profile->ext_grp_shp_profileId;
                    cmd = DRV_IOW(DsQMgrExtGrpShpProfId_t, DsQMgrExtGrpShpProfId_profId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));

                    for (queue_offset = 0; queue_offset < SYS_MAX_QUEUE_OFFSET_PER_EXT_GROUP; queue_offset++)
                    {
                        field_val = p_shp_profile->ext_queue_shp_profileId[queue_offset];
                        cmd = DRV_IOW(DsQMgrExtQueShpProfId_t, DsQMgrExtQueShpProfId_profId_f);
                        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (group_id * 4 + queue_offset), cmd, &field_val));
                    }

                }
            }
        }
        else if (DRV_IS_TSINGMA(lchip))
        {
            field_val = 0;
            cmd = DRV_IOW(DsQMgrNetChanMiscCfg_t, DsQMgrNetChanMiscCfg_flushValid_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
        }

        /*1.1 enable queue guarantee*/
        cmd = DRV_IOR(QMgrEnqReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &enq_rsv));
        field_val = GetQMgrEnqReserved(V, reserved_f, &enq_rsv);
        SetQMgrEnqReserved(V, reserved_f, &enq_rsv, field_val | 0x38);/*set bit 3 and 4*/
        cmd = DRV_IOW(QMgrEnqReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &enq_rsv));

        /*2. Disable Drop incoming channel packets*/
        cmd = DRV_IOR(DsErmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &port_cfg));
        SetDsErmPortCfg(V, portLimitedThrdProfId_f, &port_cfg, 0xF);
        SetDsErmPortCfg(V, portGuaranteedThrdProfId_f, &port_cfg, p_usw_queue_master[lchip]->p_chan_guar_profileid[chan_id]);
        cmd = DRV_IOW(DsErmPortCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &port_cfg));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_get_port_depth(uint8 lchip, uint32 chan_id, uint32* p_depth)
{
#if (SDB_MEM_MODEL == SDB_MODE)
    return CTC_E_NONE;
#endif
    uint32 cmd = 0;
    uint32 field_val = 0;

    CTC_PTR_VALID_CHECK(p_depth);

    cmd = DRV_IOR(DsErmPortCnt_t, DsErmPortCnt_portCnt_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));

    *p_depth = field_val;

    return CTC_E_NONE;
}

int32
sys_usw_qos_drop_dump_status(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 irm_sc[4] = {0};
    uint8 i = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------Queue Drop-----------------------\n");
    if (!DRV_FROM_TMM(lchip))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Total WTD drop profile", p_usw_queue_master[lchip]->p_drop_wtd_profile_pool->max_count);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--Used count", p_usw_queue_master[lchip]->p_drop_wtd_profile_pool->count);
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Total WRED drop profile", p_usw_queue_master[lchip]->p_drop_wred_profile_pool->max_count);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n","--Used count", p_usw_queue_master[lchip]->p_drop_wred_profile_pool->count);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");

    if (!DRV_FROM_TMM(lchip))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s\n", "Reserv profile id");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--default pool", p_usw_queue_master[lchip]->egs_pool[0].default_profile_id);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--non-drop pool", p_usw_queue_master[lchip]->egs_pool[1].default_profile_id);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--span pool", p_usw_queue_master[lchip]->egs_pool[2].default_profile_id);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--control pool", p_usw_queue_master[lchip]->egs_pool[3].default_profile_id);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------Pause profile-----------------------\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Normal Pause total profile", p_usw_queue_master[lchip]->p_fc_profile_pool->max_count);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--Used count", p_usw_queue_master[lchip]->p_fc_profile_pool->count);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Priority Pause total profile", p_usw_queue_master[lchip]->p_pfc_profile_pool->max_count);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--Used count", p_usw_queue_master[lchip]->p_pfc_profile_pool->count);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");
    }

    {
        DsErmScThrd_m erm_sc_thrd;
        DsErmMiscThrd_m erm_misc_thrd;
        DsIrmMiscThrd_m irm_misc_thrd;

        sal_memset(&erm_sc_thrd, 0, sizeof(DsErmScThrd_m));
        sal_memset(&erm_misc_thrd, 0, sizeof(DsErmMiscThrd_m));
        sal_memset(&irm_misc_thrd, 0, sizeof(DsIrmMiscThrd_m));
        cmd = DRV_IOR(DsErmScThrd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_sc_thrd));
        for (i = 0; i < 4; i++)
        {
            cmd = DRV_IOR(DsIrmScThrd_t, DsIrmScThrd_scThrd_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, i, cmd, &irm_sc[i]));
        }

        cmd = DRV_IOR(DsErmMiscThrd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_thrd));
        cmd = DRV_IOR(DsIrmMiscThrd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &irm_misc_thrd));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------Resrc status-----------------------\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Ingress resrc mode", p_usw_queue_master[lchip]->igs_resrc_mode[0]);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--Total thrd", GetDsIrmMiscThrd(V, totalThrd_f, &irm_misc_thrd));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC0 thrd", irm_sc[0]*(DRV_FROM_TMM(lchip) ? 1 : 8));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC1 thrd", irm_sc[1]*(DRV_FROM_TMM(lchip) ? 1 : 8));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC2 thrd", irm_sc[2]*(DRV_FROM_TMM(lchip) ? 1 : 8));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC3 thrd", irm_sc[3]*(DRV_FROM_TMM(lchip) ? 1 : 8));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Egress  resrc mode", p_usw_queue_master[lchip]->egs_resrc_mode[0]);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--Total thrd", GetDsErmMiscThrd(V, totalThrd_f, &erm_misc_thrd));
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC0 thrd", GetDsErmScThrd(V, g_0_scThrd_f, &erm_sc_thrd)*8);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC1 thrd", GetDsErmScThrd(V, g_1_scThrd_f, &erm_sc_thrd)*8);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC2 thrd", GetDsErmScThrd(V, g_2_scThrd_f, &erm_sc_thrd)*8);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "--SC3 thrd", GetDsErmScThrd(V, g_3_scThrd_f, &erm_sc_thrd)*8);
    }
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");
    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_fc_default_profile(uint8 lchip, uint32 gport)
{
    uint8 priority_class = 0;
    ctc_qos_resrc_fc_t fc;
    uint32 port_type = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&fc, 0, sizeof(ctc_qos_resrc_fc_t));

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    if ((SYS_DMPS_NETWORK_PORT != port_type) && (SYS_DMPS_CPUMAC_NETWORK_PORT != port_type))
    {
         return CTC_E_NONE;
    }

    fc.xon_thrd = 240;
    fc.xoff_thrd = 256;
    fc.drop_thrd = MCHIP_CAP(SYS_CAP_QOS_QUEUE_MAX_DROP_THRD);
    fc.gport = gport;
    fc.is_pfc = 0;
    for (priority_class = 0; priority_class < 8; priority_class++)
    {
        fc.priority_class = priority_class;
        CTC_ERROR_RETURN(sys_usw_qos_fc_add_profile(lchip, &fc));
    }

    if (DRV_IS_TSINGMA(lchip))
    {
        DsIrmPortStallInfo_m stall_info;
        uint32 chan_id = 0;
        uint32 cmd = 0;

        sal_memset(&stall_info, 0, sizeof(DsIrmPortStallInfo_m));
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, (void *)&chan_id));

        cmd = DRV_IOW(DsIrmPortStallInfo_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id&0x3F, cmd, &stall_info));
    }

    return CTC_E_NONE;
}

int32
sys_usw_queue_set_egs_pool_resrc_prof(uint8 lchip, uint8 pool)
{
    uint16 chan_id = 0;
    uint8 queue_offset = 0;
    uint8  profile_id = 0;
    uint8  gchip = 0;
    uint32 cmd = 0;
    uint32 index = 0;
    DsErmQueueCfg_m erm_queue_cfg;
    sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    profile_id = p_usw_queue_master[lchip]->egs_pool[pool].default_profile_id;
    if(pool == CTC_QOS_EGS_RESRC_SPAN_POOL)
    {
        for (chan_id = 0; chan_id < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); chan_id++)
        {
            if (!SYS_IS_NETWORK_CHANNEL(chan_id))
            {
                continue;
            }
            for (queue_offset = 0; queue_offset < 2; queue_offset ++)
            {
                index = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (chan_id * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + queue_offset;
                cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
                SetDsErmQueueCfg(V, queueLimitedThrdProfId_f, &erm_queue_cfg, profile_id);
                cmd = DRV_IOW(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
            }
        }
    }
    else if(pool == CTC_QOS_EGS_RESRC_CONTROL_POOL)
    {
        for(index = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP); index < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC); index ++)
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
            SetDsErmQueueCfg(V, queueLimitedThrdProfId_f, &erm_queue_cfg, profile_id);
            cmd = DRV_IOW(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_qos_set_fcdl_interval(uint8 lchip, uint32 time)
{
    uint32 value = 0;
    uint32 value1 = 0;
    uint32 cmd = 0;
    uint8 step_mac = 0;
    uint8 step_dp = 0;
    uint8 loop1 = 0;
    uint8 loop2 = 0;
    RefDivCpuMacPulse_m cpumac_pause_pulse;
    CTC_VALUE_RANGE_CHECK(time, 1, SYS_MAX_FCDL_INTERVAL_TIME);
    sal_memset(&cpumac_pause_pulse, 0, sizeof(RefDivCpuMacPulse_m));
    /* time = cfgRefDivSgmacPauseLockPulse[30:8] * 6.4ns */
    value =  (time * 156250) << 8;
    value1 = 0;
    if(DRV_FROM_TMM(lchip))
    {
        step_mac = RefDivMcMacPulse_cfgRefDivMcMac1Dp0SgmacPauseLockPulse_f - RefDivMcMacPulse_cfgRefDivMcMac0Dp0SgmacPauseLockPulse_f;
        step_dp = RefDivMcMacPulse_cfgRefDivMcMac0Dp1SgmacPauseLockPulse_f - RefDivMcMacPulse_cfgRefDivMcMac0Dp0SgmacPauseLockPulse_f;
        for (loop1 = 0; loop1 < MCHIP_CAP(SYS_CAP_TXQM_NUM_PER_DP); loop1++)
        {
            for (loop2 = 0; loop2 < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); loop2++)
            {
                cmd = DRV_IOW(RefDivMcMacPulse_t, RefDivMcMacPulse_cfgRefDivMcMac0Dp0SgmacPauseLockPulse_f + step_mac * loop1 + step_dp *loop2);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
                cmd = DRV_IOW(RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseLockPulse_f + step_mac * loop1 + step_dp *loop2);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value1));
            }
        }

        cmd = DRV_IOR(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpumac_pause_pulse));
        SetRefDivCpuMacPulse(V, cfgRefDivCpuMacPauseLockPulse_f, &cpumac_pause_pulse, value);
        SetRefDivCpuMacPulse(V, cfgResetDivCpuMacPauseLockPulse_f, &cpumac_pause_pulse, value1);
        cmd = DRV_IOW(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cpumac_pause_pulse));
    }
    else
    {
        cmd = DRV_IOW(RefDivSgmacPauseLockPulse_t, RefDivSgmacPauseLockPulse_cfgRefDivSgmacPauseLockPulse_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_set_fcdl_action(uint8 lchip, uint32 action)
{
    uint8 gchip = 0;
    uint8 pfc_en = 0;
    uint16 loop = 0;
    uint16 loop2 = 0;
    uint32 cmd = 0;
    uint32 gport = 0;
    ErmMiscCtl_m erm_misc_ctl;
    sys_fcdl_info_t* p_fcdl_info = NULL;
    sys_usw_get_gchip_id(lchip, &gchip);

    for(loop = 0; loop < SYS_USW_MAX_PORT_NUM_PER_CHIP; loop++)
    {
        if(p_usw_queue_master[lchip]->fcdl_info[loop].count[0]
            ||p_usw_queue_master[lchip]->fcdl_info[loop].count[1])
        {
            break;
        }
    }
    if(loop != SYS_USW_MAX_PORT_NUM_PER_CHIP)
    {
        return CTC_E_NOT_READY;
    }
    CTC_MAX_VALUE_CHECK(action, CTC_QOS_FCDL_ACTION_MAX - 1);
    p_usw_queue_master[lchip]->fcdl_action = action;

    /*recover mode 1 drop config*/
    for(loop = 0; loop < SYS_USW_MAX_PORT_NUM_PER_CHIP && (action == CTC_QOS_FCDL_ACTION_TRANSIMIT); loop++)
    {
        p_fcdl_info = &(p_usw_queue_master[lchip]->fcdl_info[loop]);
        if(p_fcdl_info->mode != 1)
        {
            continue;
        }
        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, loop);
        for (loop2 = 0; loop2 < CTC_MAX_FCDL_DETECT_NUM; loop2++)
        {
            if(p_fcdl_info->pri_class[loop2]&0x40)
            {
                /*recv incoming packets*/
                _sys_usw_qos_fcdl_recover_get_fc_type(lchip, gport, &pfc_en);
                _sys_usw_qos_fcdl_recover_drop_pkt(lchip, gport, (p_fcdl_info->pri_class[loop2]&0x7), FALSE, pfc_en);
                p_fcdl_info->pri_class[loop2] = p_fcdl_info->pri_class[loop2]&0xBF;
            }
        }
    }

    /*set for drop pkt*/
    cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    SetErmMiscCtl(V, thrdPassMode_f, &erm_misc_ctl, action == CTC_QOS_FCDL_ACTION_DROP ? 0 : 7);
    cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));

    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
    return CTC_E_NONE;
}

int32
sys_usw_qos_get_fcdl_action(uint8 lchip, uint32* action)
{
    CTC_PTR_VALID_CHECK(action);
    *action = p_usw_queue_master[lchip]->fcdl_action;
    return CTC_E_NONE;
}

int32
sys_usw_qos_fcdl_get_recover_state(uint8 lchip, uint32 gport, uint8 pri_class, uint8* state)
{
    uint16 lport = 0;
    sys_fcdl_info_t* p_fcdl_info = NULL;
    CTC_PTR_VALID_CHECK(state);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    CTC_MAX_VALUE_CHECK(pri_class, 7);

    p_fcdl_info = &(p_usw_queue_master[lchip]->fcdl_info[lport]);
    if(((p_fcdl_info->pri_class[0]&0x7) == pri_class && (p_fcdl_info->pri_class[0]&0x80))
        || ((p_fcdl_info->pri_class[1]&0x7) == pri_class && (p_fcdl_info->pri_class[1]&0x80)))
    {
        *state = CTC_QOS_FCDL_STATE_DEADLOCK;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_fcdl_recover_get_fc_type(uint8 lchip, uint32 gport, uint8* pfc_en)
{
    uint8  is_pfc = 0;
    uint8  dp_id = 0;
    uint8  lmac_id = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 tmp_mac_id = 0;
    uint32 rx_pause_type[5] = {0};
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&tmp_mac_id));/*for tm, mac id, not mac tbl id*/
    if(DRV_FROM_TMM(lchip))
    {
        if (tmp_mac_id >= SYS_CPU_MAC_ID_MIN && tmp_mac_id <= SYS_CPU_MAC_ID_MAX)
        {
            dp_id = (tmp_mac_id - SYS_CPU_MAC_ID_MIN) / MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP);
            cmd = DRV_IOR(NetRxPauseReqCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &ds));
            field_value = GetNetRxPauseReqCtl(V, cfgCpuMacPauseType_f, &ds);
            is_pfc = CTC_IS_BIT_SET(field_value, ((tmp_mac_id - SYS_CPU_MAC_ID_MIN)&0x1));
        }
        else
        {
            dp_id = tmp_mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
            lmac_id = tmp_mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
            cmd = DRV_IOR(NetRxPauseReqCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, dp_id, cmd, &ds));
            GetNetRxPauseReqCtl(A, netRxPauseType_f, &ds, rx_pause_type);
            is_pfc = CTC_IS_BIT_SET(rx_pause_type[lmac_id >> 5], (lmac_id&0x1F));
        }
    }
    else
    {
        lmac_id =  tmp_mac_id&0x3F;
        cmd = DRV_IOR(NetRxPauseReqCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
        GetNetRxPauseReqCtl(A, netRxPauseType_f, &ds, rx_pause_type);
        is_pfc = CTC_IS_BIT_SET(rx_pause_type[lmac_id >> 5], (lmac_id&0x1F));
    }

    *pfc_en = is_pfc;
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_fcdl_recover_ignore_pfc_rx(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable, uint8 pfc_en)
{
    ctc_port_fc_prop_t p_fc_prop;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "ignore pfc rx: gport=%d, pri_class=%d, enable=%d\n", gport, pri_class, enable);
    sal_memset(&p_fc_prop, 0, sizeof(p_fc_prop));
    p_fc_prop.gport = gport;
    p_fc_prop.dir = CTC_INGRESS;
    p_fc_prop.is_pfc = pfc_en;
    p_fc_prop.priority_class = pri_class;
    p_fc_prop.enable = enable ? FALSE : TRUE;
    CTC_ERROR_RETURN(SYS_CB(SYS_CB_QOS_SET_FLOW_CONTROL, lchip, (void*)&p_fc_prop, 1));
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "ignore pfc rx: p_fc_prop.gport=%d, p_fc_prop.dir=%d, p_fc_prop.is_pfc=%d, "
                                    "p_fc_prop.priority_class=%d,p_fc_prop.enable=%d\n", p_fc_prop.gport, p_fc_prop.dir,
                                    p_fc_prop.is_pfc,p_fc_prop.priority_class,p_fc_prop.enable);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_fcdl_recover_drop_pkt(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable, uint8 pfc_en)
{
    uint32 chan_id = 0;
    uint16 queue_id = 0;
    uint32 cmd = 0;
    ctc_qos_queue_id_t queue;
    sys_queue_node_t* p_sys_queue_node = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ds_t ds;

    dmps_port_info.gport = gport;
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "drop pkt: gport=%d, pri_class=%d, enable=%d, pfc_en=%d\n", gport, pri_class, enable, pfc_en);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (SYS_COMMON_USELESS_CHANNEL == chan_id)
    {
        return CTC_E_INVALID_PORT;
    }

    sal_memset(&queue, 0, sizeof(queue));
    queue.gport = gport;
    queue.queue_id = pri_class;
    queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &queue, &queue_id));
    p_sys_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec, queue_id);
    if (NULL == p_sys_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    if(MCHIP_QOS(lchip)->qos_fcdl_recover_drop_pkt)
    {
        return MCHIP_QOS(lchip)->qos_fcdl_recover_drop_pkt(lchip, (void*)p_sys_queue_node, queue_id, chan_id, enable, pfc_en);
    }
    else
    {
        if(pfc_en)
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, queue_id, cmd, ds));
            SetDsErmQueueCfg(V, queueLimitedThrdProfId_f, ds, enable ? 1 : p_sys_queue_node->drop_wtd_profile_id);
            SetDsErmQueueCfg(V, queueGuaranteedThrdProfId_f, ds, enable ? 7 : p_sys_queue_node->guarantee_profile_id);
            cmd = DRV_IOW(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, queue_id, cmd, ds));
        }
        else
        {
            cmd = DRV_IOR(DsErmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, ds));
            p_usw_queue_master[lchip]->p_chan_guar_profileid[chan_id] = enable ? GetDsErmPortCfg(V, portGuaranteedThrdProfId_f, ds)
               : p_usw_queue_master[lchip]->p_chan_guar_profileid[chan_id];
            SetDsErmPortCfg(V, portLimitedThrdProfId_f, ds, enable ? 0 : 0xF);
            SetDsErmPortCfg(V, portGuaranteedThrdProfId_f, ds, enable ? 7 : p_usw_queue_master[lchip]->p_chan_guar_profileid[chan_id]);
            cmd = DRV_IOW(DsErmPortCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, ds));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_fcdl_recover(uint8 lchip, uint32 gport, uint8 pri_class, uint8 enable)
{
    uint8  pfc_en = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "recover gport=%d, pri_class=%d, enable=%d\n", gport, pri_class, enable);

    /*disable flowctl*/
    if (DRV_FROM_AT(lchip))
    {
        if (MCHIP_QOS(lchip)->qos_fcdl_recover)
        {
            CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_fcdl_recover(lchip, gport, pri_class, enable));
        }
    }
    else
    {
        /*get pfc or fc*/
        CTC_ERROR_RETURN(_sys_usw_qos_fcdl_recover_get_fc_type(lchip, gport, &pfc_en));
        CTC_ERROR_RETURN(_sys_usw_qos_fcdl_recover_ignore_pfc_rx(lchip, gport, pri_class, enable, pfc_en));

        /*drop incoming packets*/
        if (p_usw_queue_master[lchip]->fcdl_action == CTC_QOS_FCDL_ACTION_DROP)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_fcdl_recover_drop_pkt(lchip, gport, pri_class, enable, pfc_en));
        }
    }

    return CTC_E_NONE;
}

STATIC void
_sys_usw_qos_fcdl_recover_handler(void* arg)
{
    uint8 lchip = (uintptr)arg;
    uint8 gchip = 0;
    uint8 loop = 0;
    int16 lport = 0;
    ctc_qos_fcdl_event_t event;
    CTC_INTERRUPT_EVENT_FUNC event_cb = NULL;
    sys_fcdl_info_t* p_fcdl_info = NULL;
    CTC_ERROR_DUMP(sys_usw_get_gchip_id(lchip, &gchip));
    CTC_ERROR_DUMP(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_FCDL_DETECT, &event_cb));
#if 0
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
#endif
    for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
    {
        p_fcdl_info = &(p_usw_queue_master[lchip]->fcdl_info[lport]);
        sal_memset(&event, 0, sizeof(event));
        event.gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
        {
            if(p_fcdl_info->pri_class[loop]&0x80)
            {
#if 0
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lport=%d, pri_class=%d, rcover_count=%d\n",
                                                        lport, p_fcdl_info->pri_class[loop]&0x7, p_fcdl_info->count[loop]);
#endif
                p_fcdl_info->count[loop] = p_fcdl_info->mode != 2 ? 0 : p_fcdl_info->count[loop];
                if(p_fcdl_info->count[loop])
                {
                    p_fcdl_info->count[loop]--;
                }
                else
                {
                    /*enable flowctl & recv incoming packets*/
                    CTC_ERROR_DUMP(_sys_usw_qos_fcdl_recover(lchip, event.gport, (p_fcdl_info->pri_class[loop]&0x7), FALSE));

                    /*report revocer state &unset valid config, indicate recover end*/
                    event.state[loop] = CTC_QOS_FCDL_STATE_RECOVER_DONE;
                    event.pri_class[loop] = p_fcdl_info->pri_class[loop]&0x7;
                    p_fcdl_info->pri_class[loop] = p_fcdl_info->pri_class[loop]&0x7F;
                }
            }
        }
        if(event_cb && (event.state[0] || event.state[1]))
        {
            event_cb(gchip, &event);
        }
    }
}

int32
sys_usw_qos_fcdl_timer_en(uint8 lchip, uint8 enable)
{
    uint8  loop = 0;
    uint8  gchip = 0;
    uint16 lport = 0;
    uint32 gport = 0;
    uintptr lchip_tmp = lchip;
    sys_fcdl_info_t *p_fcdl_info = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "fcdl timer enbale = %d\n", enable);
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    if (enable)
    {
        if (!p_usw_queue_master[lchip]->p_recover_timer)
        {
            CTC_ERROR_RETURN(sal_timer_create(&(p_usw_queue_master[lchip]->p_recover_timer), _sys_usw_qos_fcdl_recover_handler, (void*)lchip_tmp));
        }
        else
        {
            sal_timer_stop(p_usw_queue_master[lchip]->p_recover_timer);
        }
        sal_timer_start(p_usw_queue_master[lchip]->p_recover_timer, SYS_MAX_FCDL_RECOVER_INTERVAL);
    }
    else
    {
        if (p_usw_queue_master[lchip]->p_recover_timer)
        {
            sal_timer_stop(p_usw_queue_master[lchip]->p_recover_timer);

            for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
            {
                p_fcdl_info = &(p_usw_queue_master[lchip]->fcdl_info[lport]);
                for (loop = 0; loop < CTC_MAX_FCDL_DETECT_NUM; loop++)
                {
                    if (p_fcdl_info->pri_class[loop]&0x80)
                    {
                        /*enable flowctl & recv incoming packets*/
                        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
                        CTC_ERROR_DUMP(_sys_usw_qos_fcdl_recover(lchip, gport, (p_fcdl_info->pri_class[loop]&0x7), FALSE));
                        p_fcdl_info->count[loop] = 0;
                        p_fcdl_info->pri_class[loop] = 0; /*unset valid config, indicate recover end*/
                    }
                }
            }
        }
    }
    return CTC_E_NONE;
}

int32
_sys_usw_qos_fcdl_event_cb(uint8 gchip, void* p_data)
{
    ctc_qos_fcdl_event_t* event = (ctc_qos_fcdl_event_t*)p_data;
#ifdef CTC_SHELL_DEBUG_ON
    uint8 lchip = 0;
    CTC_ERROR_RETURN(sys_usw_get_local_chip_id(gchip, &lchip));
#endif
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,"gport = %d,pri_class0 = %d,state0 = %d,pri_class1 = %d,state1 = %d\n",
                                event->gport,event->pri_class[0],event->state[0],event->pri_class[1],event->state[1]);
    return CTC_E_NONE;
}

int32
sys_usw_qos_fcdl_state_isr(uint8 lchip, uint16 mac_id)
{
    uint8  gchip = 0;
    uint8  loop = 0;
    uint8  loop_end = 0;
    CTC_INTERRUPT_EVENT_FUNC event_cb;
    ctc_qos_fcdl_event_t event;
    uint32 cmd = 0;
    uint32 step = 0;
    uint32 step_mac = 0;
    uint32 step_det = 0;
    uint32 step_qm = 0;
    uint32 tbl_id = 0;
    uint32 tbl_id2 = 0;
    uint16 tbl_idx = 0;
    uint16 lport = 0;
    uint32 index = 0;
    uint32 tmp_mac_id = mac_id; /*tm:mac tbl id,tmm: mac id*/
    sys_fcdl_info_t* p_fcdl_info = NULL;

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    sal_memset(&event, 0, sizeof(ctc_qos_fcdl_event_t));
    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_FCDL_DETECT, &event_cb));
    lport = DRV_IS_TSINGMA(lchip) ? sys_usw_dmps_get_lport_with_mac_tbl_id(lchip, mac_id)
                                  : sys_usw_port_api_get_lport_with_mac(lchip, mac_id);
    CTC_ERROR_RETURN(lport == SYS_COMMON_USELESS_MAC ? CTC_E_INVALID_PORT : CTC_E_NONE);
    event.gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);

    if(DRV_FROM_TMM(lchip) && !DRV_IS_TMG(lchip))
    {
        if (tmp_mac_id >= SYS_CPU_MAC_ID_MIN && tmp_mac_id <= SYS_CPU_MAC_ID_MAX)
        {
            Sgmac0RxPauseLockDet0_m sgmac_lockdet;
            Sgmac0RxPauseCfg_m sgmac_rx_pause_ctl;
            uint32 sgmac_tbl_id0[SYS_USW_CPU_MAC_NUM] = {Sgmac0RxPauseLockDet0_t, Sgmac1RxPauseLockDet0_t,
                                                         Sgmac2RxPauseLockDet0_t, Sgmac3RxPauseLockDet0_t};
            uint32 sgmac_tbl_id1[SYS_USW_CPU_MAC_NUM] = {Sgmac0RxPauseLockDet1_t, Sgmac1RxPauseLockDet1_t,
                                                         Sgmac2RxPauseLockDet1_t, Sgmac3RxPauseLockDet1_t};
            uint32 sgmac_cfg_tbl_id[SYS_USW_CPU_MAC_NUM] = {Sgmac0RxPauseCfg_t, Sgmac1RxPauseCfg_t,
                                                            Sgmac2RxPauseCfg_t, Sgmac3RxPauseCfg_t};
            index = DRV_IS_AT(lchip) ? (tmp_mac_id - SYS_CPU_MAC_ID_MIN)%MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_CORE) : (tmp_mac_id - SYS_CPU_MAC_ID_MIN);
            tbl_id = sgmac_tbl_id0[index];
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_lockdet));
            event.state[0] = GetSgmac0RxPauseLockDet0(V, dbgSgmac0RxPauseLockDetect0_f, &sgmac_lockdet);
            SetSgmac0RxPauseLockDet0(V, dbgSgmac0RxPauseLockDetect0_f, &sgmac_lockdet , 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_lockdet));

            tbl_id = sgmac_tbl_id1[index];
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_lockdet));
            event.state[1] = GetSgmac0RxPauseLockDet1(V, dbgSgmac0RxPauseLockDetect1_f, &sgmac_lockdet);
            SetSgmac0RxPauseLockDet1(V, dbgSgmac0RxPauseLockDetect1_f, &sgmac_lockdet , 0);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_lockdet));

            tbl_id = sgmac_cfg_tbl_id[index];
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_rx_pause_ctl));
            event.pri_class[0] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos0_f, &sgmac_rx_pause_ctl);
            event.pri_class[1] = GetSgmac0RxPauseCfg(V, cfgSgmac0RxPauseLockDetectCos1_f, &sgmac_rx_pause_ctl);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &sgmac_rx_pause_ctl));
        }
        else
        {
            McMacPauseRxCtl_m pause_rx_Ctl;
            uint16 field_id[2] = {McMacPauseRxCtl_mcMacPauseRxCfg_0_dbgMcMacRxPauseLockDetect0_f,
                                  McMacPauseRxCtl_mcMacPauseRxCfg_1_dbgMcMacRxPauseLockDetect0_f};
            sal_memset(&pause_rx_Ctl, 0, sizeof(McMacPauseRxCtl_m));
            if (DRV_FROM_AT(lchip) && (mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)))
            {
                lchip = SYS_PP_BASE(lchip) + PP_NUM_PER_CORE;
                tmp_mac_id -= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
            }
            tbl_idx = tmp_mac_id / MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM);
            step = tmp_mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM) * (field_id[1] - field_id[0]);
            cmd = DRV_IOR(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &pause_rx_Ctl));

            event.pri_class[0] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos0_f + step, &pause_rx_Ctl);
            event.pri_class[1] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_cfgMcMacRxPauseLockDetectCos1_f + step, &pause_rx_Ctl);
            if (DRV_FROM_AT(lchip))
            {
                uint8 tbl_step = (McMacPauseRxPort1LockDetect0_t - McMacPauseRxPort0LockDetect0_t) * (tmp_mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_QM));
                McMacPauseRxPort0LockDetect0_m rx_lock_state;
                cmd = DRV_IOR(McMacPauseRxPort0LockDetect0_t + tbl_step, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &rx_lock_state));
                event.state[0] = GetMcMacPauseRxPort0LockDetect0(V, mcMacPauseRxLockDetect0_dbgMcMacRxPauseLockDetect0_f, &rx_lock_state);
                SetMcMacPauseRxPort0LockDetect0(V, mcMacPauseRxLockDetect0_dbgMcMacRxPauseLockDetect0_f, &rx_lock_state, 0);
                cmd = DRV_IOW(McMacPauseRxPort0LockDetect0_t + tbl_step, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &rx_lock_state));

                cmd = DRV_IOR(McMacPauseRxPort0LockDetect1_t + tbl_step, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &rx_lock_state));
                event.state[1] = GetMcMacPauseRxPort0LockDetect1(V, mcMacPauseRxLockDetect0_dbgMcMacRxPauseLockDetect1_f, &rx_lock_state);
                SetMcMacPauseRxPort0LockDetect1(V, mcMacPauseRxLockDetect0_dbgMcMacRxPauseLockDetect1_f, &rx_lock_state, 0);
                cmd = DRV_IOW(McMacPauseRxPort0LockDetect1_t + tbl_step, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &rx_lock_state));
            }
            else
            {
                event.state[0] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_dbgMcMacRxPauseLockDetect0_f + step, &pause_rx_Ctl);
                event.state[1] = GetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_dbgMcMacRxPauseLockDetect1_f + step, &pause_rx_Ctl);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_dbgMcMacRxPauseLockDetect0_f + step, &pause_rx_Ctl, 0);
                SetMcMacPauseRxCtl(V, mcMacPauseRxCfg_0_dbgMcMacRxPauseLockDetect1_f + step, &pause_rx_Ctl, 0);
                cmd = DRV_IOW(McMacPauseRxCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, cmd, &pause_rx_Ctl));
            }
        }
    }
    else
    {
        Sgmac0RxPauseLockDet00_m rx_pause_lockdet;
        Sgmac0RxPauseCfg0_m rx_pause_cfg;

        CTC_MAX_VALUE_CHECK(tmp_mac_id, MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM)*MCHIP_CAP(SYS_CAP_STATS_XQMAC_RAM_NUM) - 1);
        if (DRV_IS_TMG(lchip))
        {
            step_mac = Sgmac1RxPauseLockDet0_t - Sgmac0RxPauseLockDet0_t;
            step_det = Sgmac0RxPauseLockDet1_t - Sgmac0RxPauseLockDet0_t;
            tbl_id   = Sgmac0RxPauseLockDet0_t + step_mac * (tmp_mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            step_mac = Sgmac1RxPauseCfg_t - Sgmac0RxPauseCfg_t;
            tbl_id2  = Sgmac0RxPauseCfg_t + step_mac * (tmp_mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            index    = tmp_mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM);
        }
        else
        {
            step_mac = Sgmac1RxPauseLockDet00_t - Sgmac0RxPauseLockDet00_t;
            step_det = Sgmac0RxPauseLockDet10_t - Sgmac0RxPauseLockDet00_t;
            step_qm  = Sgmac0RxPauseLockDet01_t - Sgmac0RxPauseLockDet00_t;
            tbl_id   = Sgmac0RxPauseLockDet00_t + step_mac * (tmp_mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM))
                                                + step_qm  * (tmp_mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            step_mac = Sgmac1RxPauseCfg0_t - Sgmac0RxPauseCfg0_t;
            step_qm  = Sgmac0RxPauseCfg1_t - Sgmac0RxPauseCfg0_t;
            tbl_id2  = Sgmac0RxPauseCfg0_t + step_mac * (tmp_mac_id % MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM))
                                           + step_qm  * (tmp_mac_id / MCHIP_CAP(SYS_CAP_STATS_XQMAC_PORT_NUM));
            index    = 0;
        }
        sal_memset(&rx_pause_lockdet, 0, sizeof(Sgmac0RxPauseLockDet00_m));
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_lockdet));
        event.state[0] = GetSgmac0RxPauseLockDet00(V, dbgSgmac0RxPauseLockDetect0_f, &rx_pause_lockdet);
        SetSgmac0RxPauseLockDet00(V, dbgSgmac0RxPauseLockDetect0_f, &rx_pause_lockdet , 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_lockdet));
        tbl_id += step_det;
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_lockdet));
        event.state[1] = GetSgmac0RxPauseLockDet10(V, dbgSgmac0RxPauseLockDetect1_f, &rx_pause_lockdet);
        SetSgmac0RxPauseLockDet10(V, dbgSgmac0RxPauseLockDetect1_f, &rx_pause_lockdet , 0);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_lockdet));

        cmd = DRV_IOR(tbl_id2, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_cfg));
        event.pri_class[0] = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos0_f, &rx_pause_cfg);
        event.pri_class[1] = GetSgmac0RxPauseCfg0(V, cfgSgmac0RxPauseLockDetectCos1_f, &rx_pause_cfg);
        cmd = DRV_IOW(tbl_id2, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &rx_pause_cfg));
    }
    /*recover, only valid when deadlock detected and mode!=0*/
    p_fcdl_info = &(p_usw_queue_master[lchip]->fcdl_info[lport]);
    loop_end = (event.pri_class[0] == event.pri_class[1]) ? 1 : CTC_MAX_FCDL_DETECT_NUM;
    for(loop = 0; loop < loop_end; loop++)
    {
        if(event.state[loop] && p_fcdl_info->mode != 0)
        {
            /*1.record recover count, calculate from recover timer*/
            p_fcdl_info->count[loop] = (p_fcdl_info->timeout + SYS_MAX_FCDL_RECOVER_INTERVAL - 1) / SYS_MAX_FCDL_RECOVER_INTERVAL;
            /*2.disable flowctl & drop incoming packets*/
            CTC_ERROR_DUMP(_sys_usw_qos_fcdl_recover(lchip, event.gport, (event.pri_class[loop]&0x7), TRUE));

            /*3. set valid flag, indicate in recover*/
            p_fcdl_info->pri_class[loop] = p_fcdl_info->mode == 2 ? (event.pri_class[loop] | 0x80) :
                                           (p_fcdl_info->mode == 1 ? (event.pri_class[loop] | 0x40) : event.pri_class[loop]);
        }
    }

    if(event_cb)
    {
        event_cb(gchip, &event);
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_set_ecn_enable(uint8 lchip, uint32 enable)
{
    uint32 ecn_map_action_prof = 0;
    uint16 index = 0;
    uint32 cmd = DRV_IOW(EpeHeaderEditCtl_t, EpeHeaderEditCtl_cnActionEn_f);
    uint32 field_val = enable ? 1 : 0;
    DsEcnMappingAction_m ecn_map_action;
    ErmMiscCtl_m erm_misc_ctl;

    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    /*only TCP and UDP ECN Aware, tmm:CTC_PARSER_L4_TYPE_UDP = 2 in sdk, L4TYPE_UDP = 3 in asic */
    field_val = enable ? ((1 << CTC_PARSER_L4_TYPE_TCP)|(1<<(DRV_FROM_TMM(lchip) ? CTC_PARSER_L4_TYPE_GRE : CTC_PARSER_L4_TYPE_UDP))):0;
    cmd = DRV_IOW(EpePktProcCtl_t, EpePktProcCtl_ecnAware_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    sal_memset(&ecn_map_action, 0, sizeof(DsEcnMappingAction_m));
    sys_usw_ftm_query_table_entry_num(lchip, DsEcnMappingAction_t, &ecn_map_action_prof);
    for (index = 0; index < ecn_map_action_prof; index++)
    {
        SetDsEcnMappingAction(V, array_0_ecnAction_f, &ecn_map_action, CTC_QOS_INTER_CN_DROP);
        SetDsEcnMappingAction(V, array_1_ecnAction_f, &ecn_map_action, enable ? CTC_QOS_INTER_CN_NON_CE : CTC_QOS_INTER_CN_DROP);
        SetDsEcnMappingAction(V, array_2_ecnAction_f, &ecn_map_action, enable ? CTC_QOS_INTER_CN_NON_CE : CTC_QOS_INTER_CN_DROP);
        SetDsEcnMappingAction(V, array_3_ecnAction_f, &ecn_map_action, enable ? CTC_QOS_INTER_CN_CE : CTC_QOS_INTER_CN_DROP);
        cmd = DRV_IOW(DsEcnMappingAction_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ecn_map_action));
    }

    cmd = DRV_IOR(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    if (DRV_IS_TMG(lchip))
    {
        SetErmMiscCtl(V, ignoreAvqMaxThrdCheck2_f, &erm_misc_ctl, enable ? 1 : 0);
    }
    else
    {
        SetErmMiscCtl(V, ignoreAvqMaxThrdCheck_f, &erm_misc_ctl, enable ? 1 : 0);
    }
    cmd = DRV_IOW(ErmMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &erm_misc_ctl));
    return CTC_E_NONE;
}

int32
sys_usw_qos_get_ecn_enable(uint8 lchip, uint32* enable)
{

    uint32 cmd = DRV_IOR(EpeHeaderEditCtl_t, EpeHeaderEditCtl_cnActionEn_f);
    uint32 field_val = 0;

    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
    *enable = field_val;

    return CTC_E_NONE;
}

/*0: normal 1: ecn inband oam*/
int32
sys_usw_queue_drop_ecn_init(uint8 lchip, uint32 mode)
{
    uint8 inner_ecn = 0;
    uint8 outer_ecn = 0;
    uint8 ecn_action = 0;
    uint32 cmd      = 0;
    uint16  index = 0;
    uint8  step = 0;
    uint32 field_val = 0;
    EpePktProcCtl_m epe_pkt_ctl;
    /** Decap
    +---------+------------------------------------------------+
    |Arriving |            Arriving Outer Header               |
    |   Inner +---------+------------+------------+------------+
    |  Header | Not-ECT | ECT(0)     | ECT(1)     |     CE     |
    +---------+---------+------------+------------+------------+
    | Not-ECT | Not-ECT |Not-ECT(!!!)|Not-ECT(!!!)| <drop>(!!!)|
    |  ECT(0) |  ECT(0) | ECT(0)     | ECT(1)     |     CE     |
    |  ECT(1) |  ECT(1) | ECT(1) (!) | ECT(1)     |     CE     |
    |    CE   |      CE |     CE     |     CE(!!!)|     CE     |
    +---------+---------+------------+------------+------------+
    */

    /** Encap
    +-----------------+-------------------------------+
    | Incoming Header |    Departing Outer Header     |
    | (also equal to  +---------------+---------------+
    | departing Inner | Compatibility |    Normal     |
    |     Header)     | Mode(3168)    |    Mode(4301) |
    +-----------------+---------------+---------------+
    |    Not-ECT      |   Not-ECT     |   Not-ECT     |
    |     ECT(0)      |   Not-ECT     |    ECT(0)     |
    |     ECT(1)      |   Not-ECT     |    ECT(1)     |
    |       CE        |   Not-ECT     |      CE       |
    +-----------------+---------------+---------------+
    */
    sys_queue_drop_ecn_t decap_ecn[4][4] =
    {   {{0,0,0},
         {0,0,1},
         {0,0,2},
         {0,0,3}},

        {{0,0,0},
         {0,0,1},
         {0,0,1},
         {0,0,3}},

        {{0,0,0},
         {0,0,1},
         {0,0,2},
         {0,0,3}},

        {{1,0,0},
         {0,0,3},
         {0,0,3},
         {0,0,3}},
    };

    /** ecn_action map to ecn
    +---------+------------------------------------------------+
    |         |               ecn action                       |
    |Incoming +---------+------------+------------+------------+
    |  Header |   DROP  |  NON_DROP  |   NON_CE   |     CE     |
    +---------+---------+------------+------------+------------+
    | Not-ECT | Not-ECT |   Not-ECT  |  Not-ECT   |   Not-ECT  |
    |  ECT(0) | ECT(0)  |   ECT(0)   |   ECT(0)   |     CE     |
    |  ECT(1) |  ECT(1) |   ECT(1)   |   ECT(1)   |     CE     |
    |    CE   |   CE    |   CE       |     CE     |     CE     |
    +---------+---------+------------+------------+------------+
    */
    uint8 ecnAction2ecn[4][4] = {{0,1,2,3},
                                 {0,1,2,3},
                                 {0,1,2,3},
                                 {0,3,3,3},};
    
    uint8 ecnInBandAction2ecn[4][4] ={{0,1,2,3},
                                      {1,1,1,1},
                                      {0,0,0,0},
                                      {3,3,3,3},};

    DsTunnelEcnMapping_m tunnel_ecn_map;
    DsIpEcnMapping_m ip_ecn_map;
    DsEcnActionMappingEcn_m ecn_action_map_ecn;
    ds_t ds;
    sal_memset(&tunnel_ecn_map, 0, sizeof(DsTunnelEcnMapping_m));
    sal_memset(&ip_ecn_map, 0, sizeof(DsIpEcnMapping_m));
    sal_memset(&ecn_action_map_ecn, 0, sizeof(DsEcnActionMappingEcn_m));
    sal_memset(&ds, 0, sizeof(ds_t));

    /*Decap*/
    cmd = DRV_IOW(DsTunnelEcnMapping_t, DRV_ENTRY_FLAG);
    for (outer_ecn = 0; outer_ecn < 4; outer_ecn++)
    {
        index = outer_ecn;
        for (inner_ecn = 0; inner_ecn < 4; inner_ecn++)
        {
            step = inner_ecn * (DsTunnelEcnMapping_array_1_discard_f - DsTunnelEcnMapping_array_0_discard_f);
            SetDsTunnelEcnMapping(V, array_0_discard_f + step, &tunnel_ecn_map, decap_ecn[outer_ecn][inner_ecn].discard);
            SetDsTunnelEcnMapping(V, array_0_exceptionEn_f + step, &tunnel_ecn_map, decap_ecn[outer_ecn][inner_ecn].exception_en);
            SetDsTunnelEcnMapping(V, array_0_mappedEcnTunnel_f + step, &tunnel_ecn_map, decap_ecn[outer_ecn][inner_ecn].mapped_ecn);
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &tunnel_ecn_map));
    }

    cmd = DRV_IOW(DsIpEcnMapping_t, DRV_ENTRY_FLAG);
    for (inner_ecn = 0; inner_ecn < 4; inner_ecn++)
    {
        SetDsIpEcnMapping(V, array_0_mappedEcn_f + inner_ecn, &ip_ecn_map, inner_ecn);
    }
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ip_ecn_map));

    /*ecn_action map to ecn*/
    cmd = DRV_IOW(DsEcnActionMappingEcn_t, DRV_ENTRY_FLAG);
    for (ecn_action = 0; ecn_action < 4; ecn_action++)
    {
        index = ecn_action;
        for (outer_ecn = 0; outer_ecn < 4; outer_ecn++)
        {
            field_val = mode?ecnInBandAction2ecn[ecn_action][outer_ecn]:ecnAction2ecn[ecn_action][outer_ecn];
            SetDsEcnActionMappingEcn(V, array_0_ecnValue_f + outer_ecn, &ecn_action_map_ecn, field_val);
            SetDsEcnActionMappingEcn(V, array_0_markedEcnEn_f + outer_ecn, &ecn_action_map_ecn, ((ecn_action == 3 && outer_ecn != 3) ? 1 : 0));
        }
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ecn_action_map_ecn));
    }

    cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_pkt_ctl));
    field_val = mode?1:0;
    SetEpePktProcCtl(V, ecnIgnoreCheck_f, &epe_pkt_ctl, field_val);
    cmd = DRV_IOW(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_pkt_ctl));

    /*encap*/
    if (DRV_FROM_TMM(lchip))
    {
        for (inner_ecn = 0; inner_ecn < 4; inner_ecn++)
        {
            SetEpePktProcEcnXlateCtl(V, array_0_ecnValue_f + inner_ecn, &ds, inner_ecn);
        }
        cmd = DRV_IOW(EpePktProcEcnXlateCtl_t, DRV_ENTRY_FLAG);
    }
    else
    {
        for (inner_ecn = 0; inner_ecn < 4; inner_ecn++)
        {
            SetDsInnerEcnMappingTunnelEcn(V, array_0_ecnValue_f + inner_ecn, &ds, inner_ecn);
        }
        cmd = DRV_IOW(DsInnerEcnMappingTunnelEcn_t, DRV_ENTRY_FLAG);
    }
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));


    return CTC_E_NONE;
}

int32
sys_usw_queue_drop_init_profile(uint8 lchip, ctc_qos_global_cfg_t* p_cfg)
{
    int32 ret = CTC_E_NONE;
    sys_usw_opf_t opf;
    uint8 profile_used_cnt = 0;
    uint32 que_drop_wtd_profile_num = 0;
    uint32 que_drop_wred_profile_num = 0;
    uint32 fc_profile_num = 0;
    uint32 pfc_profile_num = 0;
    uint32 fc_dropthrd_profile_num = 0;
    uint32 pfc_dropthrd_profile_num = 0;
    uint32 queue_guarantee_profile_num = 0;
    uint32 oobfc_profile_num = 0;
    uint32 start_offset = 0;
    ctc_spool_t spool;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));

    /* init drop profile spool table */
    sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueLimitedThrdProfile_t, &que_drop_wtd_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmAqmQueueThrdProfile_t, &que_drop_wred_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortFlowControlThrdProfile_t, &fc_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortTcFlowControlThrdProfile_t, &pfc_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortLimitedThrdProfile_t, &fc_dropthrd_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsIrmPortTcLimitedThrdProfile_t, &pfc_dropthrd_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmQueueGuaranteedThrdProfile_t, &queue_guarantee_profile_num);
    sys_usw_ftm_query_table_entry_num(lchip, DsErmPortFcCfg_t, &oobfc_profile_num);/*egress oobfc-pfc*/


    /* care congest level*/
    que_drop_wtd_profile_num  = que_drop_wtd_profile_num / SYS_RESRC_MAX_CONGEST_LEVEL_NUM;
    fc_profile_num  = fc_profile_num / SYS_RESRC_MAX_CONGEST_LEVEL_NUM;
    pfc_profile_num  = pfc_profile_num / SYS_RESRC_MAX_CONGEST_LEVEL_NUM;
    fc_dropthrd_profile_num  = fc_dropthrd_profile_num / SYS_RESRC_MAX_CONGEST_LEVEL_NUM - 1;
    pfc_dropthrd_profile_num  = pfc_dropthrd_profile_num / SYS_RESRC_MAX_CONGEST_LEVEL_NUM - 1;
    queue_guarantee_profile_num = queue_guarantee_profile_num - 1;
    oobfc_profile_num = oobfc_profile_num / SYS_QOS_OOBFC_EGRESS_MAX_TC_NUM;

    /*create queue drop wred profile spool*/
    sal_memset(&spool, 0, sizeof(ctc_spool_t));
    spool.lchip = lchip;
    spool.block_num = 1;
    spool.block_size = 1;
    spool.max_count = que_drop_wred_profile_num - 1;
    spool.user_data_size = CTC_OFFSET_OF(sys_queue_drop_wred_profile_t, calc_key_len);
    spool.spool_key = (hash_key_fn)_sys_usw_queue_drop_wred_hash_make_profile;
    spool.spool_cmp = (hash_cmp_fn)_sys_usw_queue_drop_wred_hash_cmp_profile;
    spool.spool_alloc = (spool_alloc_fn)_sys_usw_queue_drop_wred_alloc_profileId;
    spool.spool_free = (spool_free_fn)_sys_usw_queue_drop_wred_free_profileId;
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = ctc_spool_create(&spool);
    if (NULL == p_usw_queue_master[lchip]->p_drop_wred_profile_pool)
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }

    if (!DRV_FROM_TMM(lchip))
    {
        /*create queue drop wtd profile spool*/
        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = que_drop_wtd_profile_num - 1;
        spool.user_data_size = CTC_OFFSET_OF(sys_queue_drop_wtd_profile_t, calc_key_len);
        spool.spool_key = (hash_key_fn)_sys_usw_queue_drop_wtd_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_queue_drop_wtd_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_queue_drop_wtd_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_queue_drop_wtd_free_profileId;
        p_usw_queue_master[lchip]->p_drop_wtd_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_drop_wtd_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error1;
        }

        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = fc_profile_num;
        spool.user_data_size = sizeof(sys_qos_fc_profile_t);
        spool.spool_key = (hash_key_fn)_sys_usw_qos_fc_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_qos_fc_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_qos_fc_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_qos_fc_free_profileId;
        p_usw_queue_master[lchip]->p_fc_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_fc_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error2;
        }

        /*fc and pfc use same struct and hash function*/
        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = pfc_profile_num;
        spool.user_data_size = sizeof(sys_qos_fc_profile_t);
        spool.spool_key = (hash_key_fn)_sys_usw_qos_fc_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_qos_fc_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_qos_pfc_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_qos_pfc_free_profileId;
        p_usw_queue_master[lchip]->p_pfc_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_pfc_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error3;
        }

        /*fc and pfc dropth use same struct and hash function*/
        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = fc_dropthrd_profile_num;
        spool.user_data_size = sizeof(sys_qos_fc_profile_t);
        spool.spool_key = (hash_key_fn)_sys_usw_qos_fc_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_qos_fc_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_qos_fc_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_qos_fc_free_profileId;
        p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error4;
        }

        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = pfc_dropthrd_profile_num;
        spool.user_data_size = sizeof(sys_qos_fc_profile_t);
        spool.spool_key = (hash_key_fn)_sys_usw_qos_fc_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_qos_fc_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_qos_pfc_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_qos_pfc_free_profileId;
        p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error5;
        }

        /* queue guarantee spool*/
        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = queue_guarantee_profile_num;
        spool.user_data_size = CTC_OFFSET_OF(sys_queue_guarantee_t, calc_key_len);
        spool.spool_key = (hash_key_fn)_sys_usw_qos_guarantee_hash_make_profile;
        spool.spool_cmp = (hash_cmp_fn)_sys_usw_qos_guarantee_hash_cmp_profile;
        spool.spool_alloc = (spool_alloc_fn)_sys_usw_qos_guarantee_alloc_profileId;
        spool.spool_free  = (spool_free_fn)_sys_usw_qos_guarantee_free_profileId;
        p_usw_queue_master[lchip]->p_queue_guarantee_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_queue_guarantee_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error6;
        }

        /*create oobfc profile spool*/
        sal_memset(&spool, 0, sizeof(ctc_spool_t));
        spool.lchip = lchip;
        spool.block_num = 1;
        spool.block_size = 1;
        spool.max_count = oobfc_profile_num;
        spool.user_data_size = sizeof(sys_qos_oobfc_profile_t);
        spool.desc = "opf-oobfc-profile";
        spool.key_size = CTC_OFFSET_OF(sys_qos_oobfc_profile_t, calc_key_len);
        spool.min_index = 2;/*2 profle used:0 default,1:disable*/
        spool.max_index = oobfc_profile_num - 3;
        p_usw_queue_master[lchip]->p_oobfc_profile_pool = ctc_spool_create(&spool);
        if (NULL == p_usw_queue_master[lchip]->p_oobfc_profile_pool)
        {
            ret = CTC_E_NO_MEMORY;
            goto error7;
        }

        /* add static profile */
        CTC_ERROR_GOTO(_sys_usw_queue_drop_add_static_profile(lchip, p_cfg), ret, error7_1);
        CTC_ERROR_GOTO(sys_usw_qos_fc_add_static_profile(lchip), ret, error7_1);

    }

    /*init queue drop wred profile opf*/
    CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_queue_drop_wred,
                                                                    1, "opf-queue-drop-wred"), ret, error8);

    opf.pool_type = p_usw_queue_master[lchip]->opf_type_queue_drop_wred;
    opf.pool_index = 0;
    profile_used_cnt = p_usw_queue_master[lchip]->p_drop_wred_profile_pool->count;
    start_offset = DRV_FROM_TMM(lchip) ? (profile_used_cnt + 1) : profile_used_cnt; /*DRV_FROM_TMM:profile 0 mean disable*/
    CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, start_offset, (que_drop_wred_profile_num - profile_used_cnt - 1)),
                   ret, error8);

    if (!DRV_FROM_TMM(lchip))
    {
        /*init queue drop wtd profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_queue_drop_wtd,
                                        1, "opf-queue-drop-wtd"), ret, error8);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_queue_drop_wtd;
        opf.pool_index = 0;
        profile_used_cnt = p_usw_queue_master[lchip]->p_drop_wtd_profile_pool->count;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, profile_used_cnt, (que_drop_wtd_profile_num - profile_used_cnt - 1)),
                       ret, error9);

        /*init fc profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_resrc_fc,
                                        1, "opf-resrc-fc"), ret, error9);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_resrc_fc;
        opf.pool_index = 0;
        profile_used_cnt = p_usw_queue_master[lchip]->p_fc_profile_pool->count;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, profile_used_cnt, (fc_profile_num - profile_used_cnt)),
                       ret, error10);

        /*init pfc profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_resrc_pfc,
                                        1, "opf-resrc-pfc"), ret, error10);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_resrc_pfc;
        opf.pool_index = 0;
        profile_used_cnt = p_usw_queue_master[lchip]->p_pfc_profile_pool->count;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, profile_used_cnt, (pfc_profile_num - profile_used_cnt)),
                       ret, error11);

        /*init fc dropth profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd,
                                        1, "opf-resrc-fc-dropthrd"), ret, error11);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd;
        opf.pool_index = 0;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, fc_dropthrd_profile_num ),
                       ret, error12);

        /*init pfc dropth profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd,
                                        1, "opf-resrc-pfc-dropthrd"), ret, error12);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd;
        opf.pool_index = 0;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, pfc_dropthrd_profile_num ),
                       ret, error13);

        /*init queue guarantee profile opf*/
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_queue_guarantee,
                                                                        1, "opf-queue-guarantee"), ret, error13);

        opf.pool_type = p_usw_queue_master[lchip]->opf_type_queue_guarantee;
        opf.pool_index = 0;
        profile_used_cnt = p_usw_queue_master[lchip]->p_queue_guarantee_pool->count;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, profile_used_cnt, (queue_guarantee_profile_num - profile_used_cnt)),
                                                                        ret, error14);
    }
    p_usw_queue_master[lchip]->fcdl_info = mem_malloc(MEM_QUEUE_MODULE, SYS_USW_MAX_PORT_NUM_PER_CHIP * sizeof(sys_fcdl_info_t));
    if (NULL == p_usw_queue_master[lchip]->fcdl_info)
    {
        ret = CTC_E_NO_MEMORY;
        goto error14;
    }
    sal_memset(p_usw_queue_master[lchip]->fcdl_info, 0, SYS_USW_MAX_PORT_NUM_PER_CHIP * sizeof(sys_fcdl_info_t));

    return CTC_E_NONE;

error14:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_guarantee);
error13:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd);

error12:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd);
error11:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc);

error10:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc);

error9:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wtd);
error8:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wred);
error7_1:
    ctc_spool_free(p_usw_queue_master[lchip]->p_oobfc_profile_pool);
    p_usw_queue_master[lchip]->p_oobfc_profile_pool = NULL;
error7:
    ctc_spool_free(p_usw_queue_master[lchip]->p_queue_guarantee_pool);
    p_usw_queue_master[lchip]->p_queue_guarantee_pool = NULL;
error6:
    ctc_spool_free(p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool);
    p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool = NULL;
error5:
    ctc_spool_free(p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool);
    p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool = NULL;
error4:
    ctc_spool_free(p_usw_queue_master[lchip]->p_pfc_profile_pool);
    p_usw_queue_master[lchip]->p_pfc_profile_pool = NULL;
error3:
    ctc_spool_free(p_usw_queue_master[lchip]->p_fc_profile_pool);
    p_usw_queue_master[lchip]->p_fc_profile_pool = NULL;
error2:
    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wtd_profile_pool = NULL;
error1:
    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wred_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = NULL;
error0:
//    ctc_spool_free(p_usw_queue_master[lchip]->p_oobfc_profile_pool);
//    p_usw_queue_master[lchip]->p_oobfc_profile_pool = NULL;
//error:
    return ret;
}

int32
sys_usw_queue_drop_deinit_profile(uint8 lchip)
{
    ctc_spool_free(p_usw_queue_master[lchip]->p_oobfc_profile_pool);
    p_usw_queue_master[lchip]->p_oobfc_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc);

    ctc_spool_free(p_usw_queue_master[lchip]->p_pfc_profile_pool);
    p_usw_queue_master[lchip]->p_pfc_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc);

    ctc_spool_free(p_usw_queue_master[lchip]->p_fc_profile_pool);
    p_usw_queue_master[lchip]->p_fc_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd);

    ctc_spool_free(p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool);
    p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd);

    ctc_spool_free(p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool);
    p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wred);

    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wred_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wtd);

    ctc_spool_free(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool);
    p_usw_queue_master[lchip]->p_drop_wtd_profile_pool = NULL;

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_queue_guarantee);

    ctc_spool_free(p_usw_queue_master[lchip]->p_queue_guarantee_pool);
    p_usw_queue_master[lchip]->p_queue_guarantee_pool = NULL;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_drop_free_node_data(void* node_data, void* user_data)
{
    sys_qos_buffer_info_tmm_t* p_buffer_info = (sys_qos_buffer_info_tmm_t*)node_data;
    mem_free(p_buffer_info);
    return CTC_E_NONE;
}

/**
 @brief Queue dropping initialization.
*/
int32
sys_usw_queue_drop_init(uint8 lchip, void *p_glb_parm)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    QWriteCtl_m  q_write_ctl;
    EpePktProcCtl_m EpePktProcCtl;
    ctc_qos_global_cfg_t * p_glb_cfg = NULL;
    p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;
    sal_memset(&q_write_ctl, 0, sizeof(QWriteCtl_m));
    p_usw_queue_master[lchip]->resrc_check_mode = 0;
    cmd = DRV_IOR(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    SetEpePktProcCtl(V, queueDepthThrd_f, &EpePktProcCtl, 0x1FFFF);
    cmd = DRV_IOW(EpePktProcCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &EpePktProcCtl));
    CTC_ERROR_GOTO(_sys_usw_queue_igs_resrc_mgr_init(lchip, p_glb_cfg), ret, error0);
    CTC_ERROR_GOTO(_sys_usw_queue_egs_resrc_mgr_init(lchip, p_glb_cfg), ret, error0);
    CTC_ERROR_GOTO(sys_usw_queue_drop_init_profile(lchip, p_glb_cfg), ret, error0);
    CTC_ERROR_GOTO(sys_usw_queue_drop_ecn_init(lchip, 0), ret, error1);

    p_usw_queue_master[lchip]->igs_resrc_mode[0] = p_glb_cfg->resrc_pool.igs_pool_mode;
    p_usw_queue_master[lchip]->igs_resrc_mode[1] = p_glb_cfg->resrc_pool2.igs_pool_mode;
    p_usw_queue_master[lchip]->egs_resrc_mode[0] = p_glb_cfg->resrc_pool.egs_pool_mode;
    p_usw_queue_master[lchip]->egs_resrc_mode[1] = p_glb_cfg->resrc_pool2.egs_pool_mode;
    /*Span-Mcast pool*/
    if (p_usw_queue_master[lchip]->egs_pool[CTC_QOS_EGS_RESRC_SPAN_POOL].egs_congest_level_num &&
        (1 == p_usw_queue_master[lchip]->enq_mode))
    {
        cmd = DRV_IOR(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));
        SetQWriteCtl(V, spanPktRewriteScEn_f, &q_write_ctl, 1);
        SetQWriteCtl(V, spanPktRewriteSc_f, &q_write_ctl, 2);
        cmd = DRV_IOW(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));
        if (!DRV_FROM_TMM(lchip))
        {
            CTC_ERROR_GOTO(sys_usw_queue_set_egs_pool_resrc_prof(lchip, CTC_QOS_EGS_RESRC_SPAN_POOL), ret, error1);
        }
    }
    if (!DRV_FROM_TMM(lchip) && p_usw_queue_master[lchip]->egs_pool[CTC_QOS_EGS_RESRC_CONTROL_POOL].egs_congest_level_num)
    {
            CTC_ERROR_GOTO(sys_usw_queue_set_egs_pool_resrc_prof(lchip, CTC_QOS_EGS_RESRC_CONTROL_POOL), ret, error1);
    }

    CTC_ERROR_GOTO(SYS_CB_REGISTER(lchip, SYS_CB_QOS_FCDL_SET_RECOVER_TIMER, sys_usw_qos_fcdl_timer_en), ret, error1);
    sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_FCDL_DETECT, _sys_usw_qos_fcdl_event_cb);

    if(!DRV_FROM_TMM(lchip))
    {
        p_usw_queue_master[lchip]->p_chan_guar_profileid = mem_malloc(MEM_QUEUE_MODULE,  sizeof(uint8)*MCHIP_CAP(SYS_CAP_CHANID_MAX));
        if (NULL == p_usw_queue_master[lchip]->p_chan_guar_profileid)
        {
            ret = CTC_E_NO_MEMORY;
            goto error1;
        }
        sal_memset(p_usw_queue_master[lchip]->p_chan_guar_profileid, 0, sizeof(uint8)*MCHIP_CAP(SYS_CAP_CHANID_MAX));
    }
    else
    {
        p_usw_queue_master[lchip]->buffer_info_vec = ctc_vector_init(MCHIP_CAP(SYS_CAP_CHANNEL_NUM)/16, 16);
        if (NULL == p_usw_queue_master[lchip]->buffer_info_vec)
        {
            ret = CTC_E_NO_MEMORY;
            goto error1;
        }
    }
    return CTC_E_NONE;

error1:
    (void)sys_usw_queue_drop_deinit_profile(lchip);
error0:
    return ret;
}

int32
sys_usw_queue_drop_deinit(uint8 lchip)
{
    (void)sys_usw_queue_drop_deinit_profile(lchip);
    sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_FCDL_DETECT, NULL);
    SYS_CB_REGISTER(lchip, SYS_CB_QOS_FCDL_SET_RECOVER_TIMER, NULL);
    if(p_usw_queue_master[lchip]->p_recover_timer)
    {
        sal_timer_destroy(p_usw_queue_master[lchip]->p_recover_timer);
        p_usw_queue_master[lchip]->p_recover_timer = NULL;
    }
    mem_free(p_usw_queue_master[lchip]->fcdl_info);
    if(p_usw_queue_master[lchip]->p_chan_guar_profileid)
    {
        mem_free(p_usw_queue_master[lchip]->p_chan_guar_profileid);
    }
    if (p_usw_queue_master[lchip]->buffer_info_vec)
    {
        ctc_vector_traverse(p_usw_queue_master[lchip]->buffer_info_vec, (vector_traversal_fn)_sys_usw_queue_drop_free_node_data, NULL);
        ctc_vector_release(p_usw_queue_master[lchip]->buffer_info_vec);
    }
    return CTC_E_NONE;
}

